Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Czy da się szybciej ?
Forum PHP.pl > Forum > Bazy danych > MySQL
Alek
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
TomASS
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.
orson
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
SongoQ
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.
Alek
@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
SongoQ
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.
Alek
- 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
DeyV
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'.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.