Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Czy da się szybciej ?
Alek
post 21.02.2006, 15:34:43
Post #1





Grupa: Zarejestrowani
Postów: 47
Pomógł: 0
Dołączył: 25.06.2003
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


Mam 2 tabele: 'informacje' i 'woj', w ktorych przechowuję informacje dotyczące danych województw.
W 'informacje' uzbierało się już ponad 50000 rekordów i niestety całość trochę zaczyna mulić.

struktura 'informacje':
id int(10) UNSIGNED
tytul text
tresc text
woj tinyint(3)
miasto varchar(255)
data_wprowadzenia date
termin_waznosci datetime
indeksy: id (UNIQUE), data_wprowadzenia, woj, termin_waznosci (INDEX)

struktura 'woj':
id tinyint(3)
nazwa varchar(255)
indeks: id (UNIQUE)


Dane pobieram zapytaniem:
  1. SELECT DISTINCT SQL_CALC_FOUND_ROWS t1.*,t2.nazwa
  2. FROM informacje
  3. AS t1, woj AS t2 WHERE t1.woj=t2.id ORDER BY t1.id DESC LIMIT 0, 15


czasem wykonanie zapytania trwa nawet 30-40 sekund sad.gif

Jak takie coś przyspieszyć żeby mogło funkcjonować w warunkach strony www - wiadomo, musi się jakoś rozsądnie wczytywać.

P.S. Przy wykonywaniu bardziej skomplikowanych zapytań (gdzie dochodzą jeszcze np. kategorie informacji, daty, terminy, dających mniej rekordów w odpowiedzi, wczytuje się dużo szybciej)

P.P.S.: ... a wogóle jak dużo rekordów pomieśli tabela MySQLa, bo może jestem przy wartości granicznej czy co...:/ ?

pozdro
Alek
Go to the top of the page
+Quote Post
TomASS
post 21.02.2006, 16:45:51
Post #2





Grupa: Zarejestrowani
Postów: 1 660
Pomógł: 13
Dołączył: 9.06.2004
Skąd: Wrocław i okolice

Ostrzeżenie: (0%)
-----


Cytat
czasem wykonanie zapytania trwa nawet 30-40 sekund

Zapytanie czy wyświetlenie wyników trwa 30-40 sekund. Napisałeś że wykonanie, jednak wolę się upewnić smile.gif

Cytat
Jak takie coś przyspieszyć żeby mogło funkcjonować w warunkach strony www - wiadomo, musi się jakoś rozsądnie wczytywać.

Możesz pomyśleć o cachowaniu danych.


Cytat
uzbierało się już ponad 50000 rekordów
.
.
.
P.P.S.: ... a wogóle jak dużo rekordów pomieśli tabela MySQLa, bo może jestem przy wartości granicznej czy co...:/ ?


MySQL może teoretycznie pomieścić nawet Terabajty danych. 50 tyś to nawet chyba nie kwalifikuje się do bazy średniej wilkości. Z taką ilością danych MySQL nie powinien mieć kłopotów.


--------------------
Go to the top of the page
+Quote Post
orson
post 21.02.2006, 17:14:56
Post #3





Grupa: Zarejestrowani
Postów: 548
Pomógł: 2
Dołączył: 19.07.2003

Ostrzeżenie: (0%)
-----


witam

sprawdzaj _po_koleii_, nie wszystkie naraz:
wywal SQL_CALC_FOUND_ROWS
wywal DISTINCT
zmień joina na inner (FROM informacje AS t1 INNER woj AS t2 ON (t1.woj=t2.id)
upewnij się że klucze są poprawne
przesortuj dane (ALTER TABLE `informacje` ORDER BY `woj`)

jak to nie pomoże pokaz EXPLAIN

ps. jak będziesz robił jedną rzecz naraz zobaczysz co pomaga i będziesz wiedział na przyszłość

ps2. jak zmienisz joina na inner sprawdź czy zakres zwracanych danych jest identyczny - te funkcje nie są równoważne ...

pozdrawiam


--------------------
Computer games don't affect kids; I mean if <span style="font-weight: bold;">Pac Man</span> affected us as kids,we would all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music.
Go to the top of the page
+Quote Post
SongoQ
post 22.02.2006, 02:17:17
Post #4





Grupa: Przyjaciele php.pl
Postów: 2 923
Pomógł: 9
Dołączył: 25.10.2004
Skąd: Rzeszów - studia / Warszawa - praca

Ostrzeżenie: (0%)
-----


Masz kilka bledow w struktorze tabeli:

1. Id musi byc primary a nie unique
2. Podobna sprawa z tabela woj
3. Zrob to na relacjach

@TomASS
Cytat
Możesz pomyśleć o cachowaniu danych.

Po co?

@orson
Cytat
przesortuj dane (ALTER TABLE `informacje` ORDER BY `woj`)

Jest zalozony indeks, wiec operacja ta jest zbedna

I podobnie twierdze jak @orson Explain i wszystko bedzie jasne.


--------------------
Go to the top of the page
+Quote Post
Alek
post 22.02.2006, 12:01:54
Post #5





Grupa: Zarejestrowani
Postów: 47
Pomógł: 0
Dołączył: 25.06.2003
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


@SongoQ

1. i 2. adlaczego unique jest wolniejszy od primary? pytam w celach dydaktycznych smile.gif
3. chodzi o to zeby zrobić dodatkową tabelę (powiedzmy info_woj) zawierającą pary informacja - województwo?
czy to nie będzie wolniejsze (do joina dojdzie tabela relacji); poza tym to jest relacja *->1, więc nie wiem czy potrzebna dodatkowa tabela


@orson
Cytat
wywal SQL_CALC_FOUND_ROWS

SQL_CALC_FOUND_ROWS potrzebne mi jest do wydobycia info dla użytkownika i do stronicowania wyników - jaka jest alternatywa? (count(id) questionmark.gif)

Cytat
wywal DISTINCT

tu faktycznie nie jest potrzebne, jest to pozostałość z większej kwerendy, gdzie używałem jeszcze kategorii informacji w relacji *->* (tabela informacje_kat)
oto ona:
  1. SELECT DISTINCT SQL_CALC_FOUND_ROWS t1.*,t2.nazwa
  2.  
  3. FROM informacje
  4. AS t1, woj AS t2, informacje_kat AS t3
  5. WHERE t1.woj=t2.id AND t1.id=t3.informacja AND t3.kat='1'
  6. ORDER BY t1.id DESC LIMIT 0, 15


stąd nie mogę wywalić, bo będą się powtarzać wiersze wynikowe; chyba że można coś z tym zrobić...


@TomASS
Cytat
Zapytanie czy wyświetlenie wyników trwa 30-40 sekund. Napisałeś że wykonanie, jednak wolę się upewnić

zapytanie, czas podany przez phpMyAdmin

Cytat
Możesz pomyśleć o cachowaniu danych.

Serwer MySQL ustawiony ma cache wewnętrzny, więc następne identyczne zapytania są wykonywane szybko; poza tym tablica się dość szybko zmienia (co kilka minut)

-------------
poniżej wynik EXPLAIN:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL woj NULL NULL NULL 55224 Using filesort
1 SIMPLE t2 eq_ref id id 1 mojabaza.t1.woj 1
Go to the top of the page
+Quote Post
SongoQ
post 23.02.2006, 03:24:01
Post #6





Grupa: Przyjaciele php.pl
Postów: 2 923
Pomógł: 9
Dołączył: 25.10.2004
Skąd: Rzeszów - studia / Warszawa - praca

Ostrzeżenie: (0%)
-----


Cytat
1 SIMPLE t1 ALL woj NULL NULL NULL 55224 Using filesort

To jest odpowiedz smile.gif do UNIQUE

Cytat
1. i 2. adlaczego unique jest wolniejszy od primary? pytam w celach dydaktycznych

Widze ze teoria sie klania, poczytaj i odpowiedz sobie sam. Co ma na zadaniu w szybkosci i w laczeniu tabel primary a co robi unique.


--------------------
Go to the top of the page
+Quote Post
Alek
post 28.02.2006, 14:33:36
Post #7





Grupa: Zarejestrowani
Postów: 47
Pomógł: 0
Dołączył: 25.06.2003
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


- zamieniłem UNIQUE na PRIMARY (w obu tabelach),
- wywaliłem DISTINCT
- na relacje nie przechodziłem bo info do woj jest w relacji *->1, wiec starczy chyba kolumna woj w tabeli info (zdaje mi się że tak bedzie szybciej nawet)
- do tego zchache'owałem w tablicy wojewodztwa, żeby nie robić złączenia

zapytanie teraz wygląda tak:
  1. SELECT SQL_CALC_FOUND_ROWS t1.*
  2. FROM informacje
  3. AS t1 ORDER BY t1.id DESC LIMIT 1000, 15


...i dalej muli
czy SQL_CALC_FOUND_ROWS tak zamula?
a jeśli tak to jak można szybciej zliczyć wyniki zapytania (do stronicowania)

p.s. EXPLAIN daje:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 55713 Using filesort
Go to the top of the page
+Quote Post
DeyV
post 28.02.2006, 16:17:13
Post #8





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Hmm - co prawda wydaje mi sie, że COUNT przy tej ilości elementów nie powinien być jeszcze zbyt wolny, szczególnie przy poprawnie założonych indexach.

Jeśli jednak w tym określonym przypadku nie chce chodzić to szybciej, to nie pozostaje nic innego, jak przechowywanie informacji o ilości "informacji" w tabeli woj, i aktualizowanie jej po każdej operacji na tabeli 'informacje'.


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 14.06.2025 - 12:52