sql >> Databasteknik >  >> RDS >> Mysql

Filtrera MySQL-frågeresultat som ger flera förekomster inom en viss tidsperiod

Om vi ​​vill filtrera bort de rader där det inte finns minst fyra föregående rader under de senaste 60 sekunderna, förutsatt att dateTimeOrigination är heltalstyp, en 32-bitars unix-stil tidsstämpel, kan vi göra något så här:

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

OBS:För prestanda föredrar vi att ha predikat på kala kolumner.

Med en form som denna, med kolumnen insvept i ett uttryck:

 WHERE FROM_UNIXTIME(r.dateTimeOrigination) LIKE '2016-05-20%'

MySQL kommer att utvärdera funktionen för varje rad i tabellen och jämför sedan avkastningen från funktionen med den bokstavliga.

Med ett formulär som detta:

 WHERE r.dateTimeOrigination >= UNIX_TIMESTAMP('2016-05-20')
   AND r.dateTimeOrigination  < UNIX_TIMESTAMP('2016-05-21')

MySQL kommer att utvärdera uttrycken på höger sida ett tid, som bokstaver . Vilket gör att MySQL effektivt kan använda en avsökningsoperation på ett lämpligt index.

UPPFÖLJNING

För bästa prestanda för den yttre frågan, skulle det bästa indexet troligen vara ett index med ledande kolumn för dateTimeOrigination, helst innehållande

... ON cdr_records (dateTimeOrigination
    ,callingPartyNumber,originalCalledPartyNumber,finalCalledPartyNumber)

För bästa prestanda, ett täckande index, för att undvika uppslagningar till sidorna i den underliggande tabellen. Till exempel:

... ON cdr_records (dateTimeOrigination
    ,callingPartyNumber,originalCalledPartyNumber,finalCalledPartyNumber
    ,duration,origDeviceName,destDeviceName)

Med det förväntar vi oss att EXPLAIN visar "Using index".

För den korrelerade underfrågan skulle vi vilja ha ett index med ledande kolumner så här:

... ON cdr_records (originalCalledPartyNumber,dateTimeOrigination)

Jag rekommenderar starkt att du tittar på utdata från EXPLAIN för att se vilka index MySQL använder för frågan.




  1. Supernyckel, kandidatnyckel och primärnyckel

  2. hur man listar kolumn i mysql på nodejs med modulen mysql

  3. mysqli-anslutningen fungerar inte inuti funktionen?

  4. Mysql - 1045 - Åtkomst nekad för användaren 'user'@'localhost' (med lösenord:Ja)