2013-06-14 42 views
9

ja po prostu znaleźć mysql może zapytać datetime przy użyciu takich jak:mysql pola datetime z indeksu uzyskać szereg „jak” vs. „pomiędzy” i osiągi

like '2013-06-12%' 

myślę, że nie można korzystać z indeksu. I Google to, ale nie mogę znaleźć takiego tematu bezpośrednio. Więc mam test używając tabeli z 3308614 rekordami. Pierwszy SQL:

Wszystko, co wiemy, ten SQL nie może korzystać z indeksu i uzyskanie wyniku trwa 4 sekundy. Drugi SQL:

SELECT * FROM subscription t WHERE t.active_time LIKE '2013-06-30%'; 

ja nie wiem, czy to może skorzystać z indeksu, ale to trwa 4 sekundy zbyt. Trzeci SQL:

SELECT * FROM subscription t WHERE t.active_time > '2007-11-30' AND t.active_time < '2007-12-01'; 

Wiemy trzeci SQL może skorzystać z indeksu, a to trwa 0,016 sekundy.

Więc myślę, że "jak" nie może używać indeksu podczas kwerendy pola datetime, ponieważ mysql powinien konwertować pole datetime na ciąg pierwszy i wysłać ciąg znaków do polecenia. Czy to prawda?

+0

"Czy to prawda?" --- yp – zerkms

+0

możesz zapytać o datę i jak to 't.active_time = '2013-06-30'' – Justin

+0

NIE może używać t.active_time =' 2013-06-30 '!! – bluearrow

Odpowiedz

13

Zakładając, że typ t.active_time „s jest DATETIME,

Następująca kwerenda nie może używać indeksu z powodu wywołania funkcji. Wszystkie wartości active_time należy przekonwertować w locie na wartość DATE przed porównaniem z '2013-06-30'. Ten ciąg jest konwertowany na wartość DATE na samym początku, a dzieje się tak tylko raz na samym początku zapytania.

SELECT * FROM subscription t WHERE DATE(t.active_time) = '2013-06-30'; 

Drugie zapytanie nie może korzystać z indeksu z podobnych powodów. W rzeczywistości dokonujesz porównania ciągów znaków (z powodu operatora LIKE). Wszystkie wartości active_time są konwertowane na ciąg w locie.

SELECT * FROM subscription t WHERE t.active_time LIKE '2013-06-30%'; 

Tylko ostatni może korzystać z indeksu. Ciągi '2007-11-30' i '2007-12-01' są w tym przypadku rzutowane na DATETIME, ponieważ umożliwiają to operatory < i >.

SELECT * FROM subscription t WHERE t.active_time > '2007-11-30' AND t.active_time < '2007-12-01'; 

To ostatnie odnosi się również do operatorów = i BETWEEN.

Dla informacji, wszystkie typy można porównać do ciągu znaków z operatorem LIKE, cierpiącym na ten sam problem, co opisany powyżej, z powodu niejawnej konwersji, której wymaga.

t.active_time = '2013-06-30' nie działa zgodnie z oczekiwaniami, ponieważ '2013-06-30' odlewa się do wartości DATETIME, to znaczy '2013-06-30 00:00:00'.

1

Jedną z alternatyw dla takich przypadków jest zrobić coś takiego:

SELECT * 
FROM subscription t 
WHERE t.active_time BETWEEN '2013-06-30 00:00:00' AND '2013-06-30 23:59:59'; 

W końcu można uzyskać wszystkie wydarzenia z tego dnia.