Als we de rijen willen uitfilteren waar er niet ten minste vier voorgaande rijen zijn in de afgelopen 60 seconden, ervan uitgaande dat dateTimeOrigination een geheel getal is, een 32-bits Unix-stijl tijdstempel, kunnen we zoiets als dit doen:
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
OPMERKING:voor prestaties geven we er de voorkeur aan predikaten op kale kolommen te hebben.
Met een formulier als dit, met de kolom verpakt in een uitdrukking:
WHERE FROM_UNIXTIME(r.dateTimeOrigination) LIKE '2016-05-20%'
MySQL evalueert de functie voor elke rij in de tabel en vergelijk vervolgens het resultaat van de functie met de letterlijke.
Met een formulier als dit:
WHERE r.dateTimeOrigination >= UNIX_TIMESTAMP('2016-05-20')
AND r.dateTimeOrigination < UNIX_TIMESTAMP('2016-05-21')
MySQL evalueert de uitdrukkingen aan de rechterkant één tijd, als letterlijk . Waardoor MySQL effectief gebruik kan maken van een bereikscanbewerking op een geschikte index.
VERVOLG
Voor de beste prestaties van de buitenste query is de beste index waarschijnlijk een index met een leidende kolom van dateTimeOrigination, bij voorkeur met
... ON cdr_records (dateTimeOrigination
,callingPartyNumber,originalCalledPartyNumber,finalCalledPartyNumber)
Voor de beste prestaties, een dekkende index, om lookups naar de pagina's in de onderliggende tabel te voorkomen. Bijvoorbeeld:
... ON cdr_records (dateTimeOrigination
,callingPartyNumber,originalCalledPartyNumber,finalCalledPartyNumber
,duration,origDeviceName,destDeviceName)
Daarmee verwachten we dat EXPLAIN "Using index" laat zien.
Voor de gecorreleerde subquery willen we een index met voorloopkolommen zoals deze:
... ON cdr_records (originalCalledPartyNumber,dateTimeOrigination)
Ik raad je ten zeerste aan om naar de uitvoer van EXPLAIN te kijken om te zien welke indexen MySQL voor de query gebruikt.