Jeśli chcemy odfiltrować wiersze, w których nie ma co najmniej czterech poprzedzających wierszy w ciągu ostatnich 60 sekund, zakładając, że dateTimeOrigination jest typem całkowitym, 32-bitowym znacznikiem czasu w stylu unix, możemy zrobić coś takiego:
SELECT FROM_UNIXTIME(r.dateTimeOrigination) AS dateTimeOrigination
, r.callingPartyNumber
, r.originalCalledPartyNumber
, r.finalCalledPartyNumber
, r.duration
, r.origDeviceName
, r.destDeviceName
FROM cdr_records r
WHERE r.dateTimeOrigination >= UNIX_TIMESTAMP('2016-05-20')
AND r.dateTimeOrigination < UNIX_TIMESTAMP('2016-05-21')
AND r.callingPartyNumber NOT LIKE 'b00%'
AND r.originalCalledPartyNumber NOT LIKE 'b00%'
AND r.finalCalledPartyNumber NOT LIKE 'b00%'
AND ( SELECT COUNT(1)
FROM cdr_records c
WHERE c.originalCalledPartyNumber = r.originalCalledPartyNumber
AND c.dateTimeOrigination > r.dateTimeOrigination - 60
AND c.dateTimeOrigination <= r.dateTimeOrigination
) > 4
ORDER
BY r.originalCalledPartyNumber
, r.dateTimeOrigination
UWAGA:Aby uzyskać wydajność, wolimy mieć predykaty na gołych kolumnach.
W formie takiej jak ta, z kolumną owiniętą w wyrażenie:
WHERE FROM_UNIXTIME(r.dateTimeOrigination) LIKE '2016-05-20%'
MySQL oceni funkcję dla każdego w tabeli, a następnie porównaj zwrot z funkcji z literałem.
W takim formularzu:
WHERE r.dateTimeOrigination >= UNIX_TIMESTAMP('2016-05-20')
AND r.dateTimeOrigination < UNIX_TIMESTAMP('2016-05-21')
MySQL oceni wyrażenia po prawej stronie jeden czas, jak litery . Co pozwala MySQL na efektywne wykorzystanie operacji skanowania zakresu na odpowiednim indeksie.
KONTYNUACJA
Aby uzyskać najlepszą wydajność zewnętrznego zapytania, najlepszym indeksem byłby prawdopodobnie indeks z wiodącą kolumną dateTimeOrigination, najlepiej zawierający
... ON cdr_records (dateTimeOrigination
,callingPartyNumber,originalCalledPartyNumber,finalCalledPartyNumber)
Aby uzyskać najlepszą wydajność, indeks pokrywający, aby uniknąć wyszukiwania stron w tabeli podstawowej. Na przykład:
... ON cdr_records (dateTimeOrigination
,callingPartyNumber,originalCalledPartyNumber,finalCalledPartyNumber
,duration,origDeviceName,destDeviceName)
W związku z tym spodziewamy się, że EXPLAIN wyświetli „Korzystanie z indeksu”.
W przypadku skorelowanego podzapytania chcielibyśmy mieć indeks z wiodącymi kolumnami w następujący sposób:
... ON cdr_records (originalCalledPartyNumber,dateTimeOrigination)
Zdecydowanie polecam spojrzeć na dane wyjściowe z EXPLAIN, aby zobaczyć, których indeksów MySQL używa do zapytania.