2013-02-19 4 views
5

miałem problemy z moim zapytaniu, które trwało 17 sekund, aby wykonać (350k wierszy):Wydajność zapytania; nie wiem, co się dzieje

SELECT idgps_unit, MAX(dt) 
     FROM gps_unit_location 
     GROUP BY 1 

Wyjaśnić

1 SIMPLE gps_unit_location index  fk_gps2 5  422633 

Po grać z nim, ja przyszedłem z tego rozwiązania, które odbywają 1 sekunda:

Select idgps_unit, MAX(dt) from (
SELECT idgps_unit, dt 
     FROM gps_unit_location 
) d1 
Group by 1 

Wyjaśnij:

1 PRIMARY <derived2> ALL     423344 Using temporary; Using filesort 
2 DERIVED gps_unit_location index  gps_unit_location_dt_gpsid 10  422617 Using index 

A teraz jestem zdezorientowany - dlaczego zapytanie # 2 jest szybkie, podczas gdy zapytanie # 1 wydaje się być tym samym zapytaniem i wydaje się być napisane bardziej wydajnie.

index1 DT, Index2: idgps_unit, Index3: idgps_unit + DT

czasy wykonania są zgodne; zapytanie # 1 zawsze trwa od 17 do 19 sekund; podczas gdy # 1 < 1sec.

Używam GoDaddy VPS Windows Server 2008 Economy

przykład Tabela:

id | idgps_unit | dt | location 
1 | 1 | 2012-01-01 | 1 
2 | 1 | 2012-01-02 | 2 
3 | 2 | 2012-01-03 | 3 
4 | 2 | 2012-01-04 | 4 
5 | 3 | 2012-01-05 | 5 
+0

mysql lub tsql?!? –

+2

Czy czas wykonywania obu zapytań jest spójny? Ponieważ jest możliwe, że wyniki są buforowane, gdy pierwsze zapytanie zostało wykonane i użyte przez drugie zapytanie. – Slowcoder

+0

Jeśli mógłbyś opublikować wynik uruchomienia 'EXPLAIN' na tych zapytaniach, może to być pomocne. –

Odpowiedz

1

Po pierwsze, zakładam, że gps_unit_location to tak naprawdę tabela, a nie widok. Po drugie, zakładam również, że wielokrotnie uruchamiałeś oba zapytania, więc buforowanie nie jest wyjaśnieniem. (Buforowanie polega na uruchomieniu pierwszej kwerendy, załadowaniu tabeli do pamięci podręcznej strony i drugiej odczytaniu z pamięci zamiast z dysku).

Czy masz indeks na gps_unit_location(idgps_unit)? Czy rekordy są bardzo szerokie? Jeśli odpowiedzi na te pytania brzmią "tak", może się zdarzyć, co następuje.

Jeśli tak, możesz mieć ciekawy problem z indeksowaniem. Można by pomyśleć, że indeks przyspieszy takie zapytanie. To, co robi, to jednak poszukać wartości w kolejności: idgps_id. Jeśli indeks nie zawiera daty, wówczas baza danych musi pobrać dane z każdej strony. Jeśli tabela nie mieści się w pamięci, często powoduje to brak pamięci podręcznej - czas ładowania strony.

W przeciwieństwie do tego, jeśli stół jest szeroki, a silnik wykonuje pełne skanowanie tabeli, to można go przekreślić tabelą i wyodrębnić dwa interesujące pola. Porzuca ich na bok. Jeśli są one małe w stosunku do pełnej tabeli, sortowanie ich może zająć bardzo mało czasu. Voila, zapytanie kończy się szybciej.

Domyślam się, że druga struktura usuwa użycie indeksu.

Nawiasem mówiąc, możesz to naprawić, zmieniając indeks na gps_unit_location(idgps_unit, dt). Uwzględniając pole w indeksie, zapytanie nie musi ładować danych.

+0

'gps_unit_location (idgps_unit, dt)' rozwiązało problem! Dziękuję Ci! – Andrew

1

powiedziałbym twoi Indexs nie są ustawione prawidłowo, Twoje drugie zapytanie jest rodzajem kwerendy wewnętrznej, która jest skutecznie tworzenie własnej wewnętrznej grupy indeksu, jeśli ma to sens!