2011-12-22 10 views
5

Mam oświadczenie SELECT, które chciałbym zoptymalizować. mysql - order by optimization mówi, że w niektórych przypadkach indeks nie może być użyty do optymalizacji ORDER BY. Konkretnie chodzi:Czy optymalizacja ORDER BY zaczyna obowiązywać w następującej instrukcji SELECT?

użyć ORDER BY na niesąsiadujące częściach kluczowy
SELECT * FROM t1 WHERE klucz2 = stała ORDER BY key_part2;

daje mi do myślenia, że ​​tak może być. Używam następujące indeksy:

UNIQUE KEY `met_value_index1` (`RTU_NB`,`DATETIME`,`MP_NB`), 
KEY `met_value_index` (`DATETIME`,`RTU_NB`) 

Z poniższego instrukcja_sql:

SELECT * FROM met_value 
WHERE rtu_nb=constant 
AND mp_nb=constant 
AND datetime BETWEEN constant AND constant 
ORDER BY mp_nb, datetime 
  • byłoby wystarczająco usunąć indeks met_value_index1 i utworzyć go z nowym zamówieniu RTU_NB, MP_NB, DATETIME?
  • Czy muszę dołączyć RTU_NB do klauzuli ORDER BY?


Rezultat: Próbowałem co @meriton zaproponował i dodał indeksu met_value_index2. The SELECT ukończył po 1,2 sekundy, poprzednio zakończył po 5,06 sekundy. Następujące kwestie nie należą do pytania, ale jako informacja dodatkowa: po kilku innych próbach przełączyłem silnik z MyISAM na InnoDB - z rtu_nb, mp_nb, datetime jako kluczem podstawowym - a instrukcja zakończona po 0,13 sekundy!

Odpowiedz

1

Nie otrzymuję zapytania. Jeśli wiersz musi być zgodny z wartością zwracaną przez mp_np = constant, wszystkie zwrócone wiersze będą miały tę samą wartość mp_nb, więc uwzględnienie mp_nb w klauzuli kolejność nie przyniesie żadnego efektu. Polecam użyć semantycznie równoważnego oświadczenia:

SELECT * FROM met_value 
WHERE rtu_nb=constant 
AND mp_nb=constant 
AND datetime BETWEEN constant AND constant 
ORDER BY datetime 

, aby uniknąć niepotrzebnego mylenia optymalizatora zapytań.

Teraz, na twoje pytanie: Baza danych może implementować porządek według klauzuli bez sortowania, jeśli wie, że podstawowy dostęp zwróci wiersze we właściwej kolejności. W przypadku indeksów oznacza to, że indeks może pomóc w sortowaniu, jeśli wiersze dopasowane klauzulą ​​where pojawią się w indeksie w kolejności żądanej przez klauzulę order by.

tak jest tutaj, więc baza danych może rzeczywiście zrobić skanowanie zakres indeksu nad met_value_index1 dla wierszy gdzie rtu_nb=constant AND datetime BETWEEN constant AND constant, a następnie sprawdzić, czy mp_nb=constant dla każdego z tych wierszy, ale to oznaczałoby sprawdzenie znacznie więcej wierszy niż to konieczne jeśli mp_nb=constant ma wysoką selektywność.Inaczej mówiąc, indeks jest najbardziej przydatny, jeśli wiersze pasujące sąsiadują z indeksem, ponieważ oznacza to, że skanowanie zakresu indeksu dotknie tylko wierszy, które faktycznie muszą zostać zwrócone.

Poniższy spis będzie zatem być bardziej pomocny dla tego zapytania:

UNIQUE KEY `met_value_index2` (`RTU_NB`,`MP_NB`, `DATETIME`), 

jak wszystkie pasujące wiersze będą obok siebie w indeksie i wiersze pojawiają się w indeksie w celu klauzula order by upraszanie. Nie mogę powiedzieć, czy optymalizator zapytań jest wystarczająco inteligentny, aby to uzyskać, więc powinieneś sprawdzić plan wykonania.

+0

Dziękuję za wyjaśnienie i sugestię. Wypróbuję to i jak najszybciej zdam sprawozdanie z wyników - obecnie zdalna maszyna jest wyłączona - i jestem ciekawa, co się zmieni. –

0

Kolejność pól wyświetlanych w klauzuli WHERE musi być zgodna z kolejnością w indeksie. Tak więc przy bieżącym zapytaniu potrzebujesz jednego indeksu z polami w kolejności rtu_nb, mp_nb, datetime.

+0

[To nie jest prawdą] (http://stackoverflow.com/questions/3805863/order-of-ands-in-where-clause-for-gestestance), a także nieistotne dla pytania. –

+0

W MySQL jest to absolutnie prawdą. Dotyczy to zwłaszcza indeksów silnika innodb. Zobacz odpowiedź merytonów lub przeczytaj podręcznik Zawodny w tej sprawie. – Anony

1

Nie sądzę, że użyje żadnego indeksu dla ORDER BY. Ale powinieneś spojrzeć na execution plan. Lub here.

Powiązane problemy