misty
22.11.2011, 08:46:12
Hej,
mam select'a na baardzo duzej tabeli. Zapytanie wyglada:
SELECT COUNT(id) AS totalResultsNumber
FROM test
WHERE 1
AND test.abc_id IN (11,12,13,14,15,16,17)
AND test.testDate >= "2011-07-22"
ORDER BY test.id DESC
to zapytanie zajmuje mi ponad 3min. Sprawdzalam bez warunku z data i bez order, czyli sam select count(id) z warunkiem test.abs_id ... - i to nadal zajmuje ponad 3min.
czy da sie jakims trickiem przyspieszyc count?
pzdr,
misty
Sephirus
22.11.2011, 09:01:05
1. Ile rekordów ma ta tabela?
2. Czy pole ID to index?
3. Czy pole abc_id to index?
Do poprawy:
"WHERE 1 AND" - to jeden jest nie potrzebne...
"ORDER BY..." - po co order jeśli uzywamy count...
Pokasuj to
misty
22.11.2011, 09:10:17
hej,
"where 1" - nie zmiania mi w tym wypadku nic (ani nie szkodzi, anie nie poprawia)
"order by" - probowalam i bez tego ale nic nie dalo
abc_id - sa to indeksy - jest to klucz obcy do tabeli abc
tabela test ma 6mln rekordow.
Jakis sposob?
Sephirus
22.11.2011, 09:30:48
hmmm ciekawe... Nie powinno to tak długo trwać... powinno owszem zając parę dobrych sekund ale nie 3 minuty :/
Może masz podpięte do tego jakieś triggery czy coś takiego - ale wątpie...
Rozumiem, że mechanizm składowania to innoDB...
ok a ile zajmuje wykonanie
SELECT COUNT(id) AS totalResultsNumber
FROM test
misty
22.11.2011, 09:44:52
hej,
tak, to innoDb. a zapytanie ktore podeslales zajelo mi 8,44 sec wiec spoko.. widocznie warunki tak spowalniaja..
wookieb
22.11.2011, 09:51:20
Zrób
SHOW CREATE TABLE test;
I pokaż wynik.
6nom
22.11.2011, 09:52:16
Czesc
A ile wynosi wynik obliczen totalResultsNumber ? Jezeli jest to jakies 1/3 calkowitej liczby rekortow, to i tak bedzie sie odbywalo skanowanie sekwencyjne, bo jest za maly wspolczynnik filtracji. Jesli jest to jakas mala liczba, to zobacz w explain czy optymalizator zapytan uzywa indeksu
phpion
22.11.2011, 10:06:23
Spróbuj takich rozwiązań:
1. Zapytanie zostaw jakie jest, ale utwórz indeks na kolumnie abc_id oraz testDate (1 indeks na 2 kolumnach).
2. Zamień warunki abc_id i testDate miejscami i utwórz indeks na kolumnie testDate oraz abc_id (1 indeks na 2 kolumnach).
Możliwe, że abc_id jest za mało selektywne i w tym przypadku lepiej sprawdzi się testDate jako pierwsza kolumna.
misty
22.11.2011, 10:13:50
hej,
tworzenie indeksow na parach nie do konca bedzie tu efektywne - ja podalam tylko przyklad, a tych 'whereConditions' moze byc troche wiecej. wiec dla kazdej pary musialabym tworzyc nowy indeks-to jeszcze ok, ale jak w whereConditions beda 2-3 warunki? bo mam tworzyc jeszcze indeksy dla id + pol z tych warunkow?
kombinacji bedzie spooro!
na wszystkich polach ktore moga wystapic w whereConditions sa utworzone indeksy.
phpion
22.11.2011, 10:19:18
Jeśli zapytanie zliczające ilość rekordów potrzebujesz do stronicowania to przemyśl inny rodzaj stronicowania. Do standardowego 1, 2, 3... potrzebujesz ilość rekordów. Jak sama widzisz - to trwa. Może więc lepiej byłoby zrobić samo poprzednia, następna? Wówczas nie potrzebujesz liczby rekordów, a operujesz jedynie na limit + offset. Jeśli jednak liczba rekordów jest Ci potrzebna do innego celu to chyba nic sensownego nie da się zrobić.
misty
22.11.2011, 10:23:03
czesc,
rozwazalam takie rozwiazanie o ktorym mowisz, ale chcialam sie wpierw upewnic ze nie da sie z tym COUNT nic zrobic..
pzdr
phpion
22.11.2011, 10:30:22
Wydaje mi się, że nie. Sam mam bazę z blisko 70 mln rekordów (PostgreSQL) i zdecydowanie najwięcej czasu zajmowało wykonanie właśnie COUNTa. Samo pobranie rekordów to była w zasadzie chwila, natomiast COUNT - masakra. Przy większej liczbie rekordów warto po prostu zrezygnować ze zliczania rekordów przy stronicowaniu. Listę rekordów otrzymasz zdecydowanie szybciej, a przecież o to chodzi.
misty
22.11.2011, 10:32:49
masz 70 mln rekordow i nie masz problemow z selectami? jakos to przyspieszyles, moze uzyles partycjonowania?
phpion
22.11.2011, 10:50:29
Partycjonowanie tak naprawdę nic nie dało. Rozbijałem rekordy w ujęciu miesięcznym, ale efekt wyszukiwania był żaden. SELECTy z warunkami trwają, to fakt, ale samo przeglądanie rekordów bez filtrowania śmiga ładnie.
wookieb
22.11.2011, 11:26:50
Co to za rekordy? Z jakimi danymi i jakie operacje robisz na tej tabeli?
Poza tym - show create table nadal nie otrzymaliśmy.
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.