sql >> Database teknologi >  >> RDS >> Mysql

Filtrerende MySQL-forespørgselsresultatsæt til at give flere forekomster inden for en bestemt tidsperiode

Hvis vi vil bortfiltrere de rækker, hvor der ikke er mindst fire foregående rækker inden for de sidste 60 sekunder, forudsat at dateTimeOrigination er heltalstypen, et 32-bit unix-stil tidsstempel, kan vi gøre noget som dette:

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

BEMÆRK:For ydeevne foretrækker vi at have prædikater på nøgne kolonner.

Med en form som denne, med kolonnen pakket ind i et udtryk:

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

MySQL vil evaluere funktionen for hver række i tabellen, og sammenlign derefter afkastet fra funktionen med det bogstavelige.

Med en formular som denne:

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

MySQL vil evaluere udtrykkene på højre side af en tid, som bogstaver . Hvilket gør det muligt for MySQL at gøre effektiv brug af en rækkeviddescanningsoperation på et passende indeks.

OPFØLGNING

For at opnå den bedste ydeevne af den ydre forespørgsel vil det bedste indeks sandsynligvis være et indeks med den førende kolonne af datoTimeOrigination, fortrinsvis indeholdende

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

For den bedste ydeevne, et dækkende indeks, for at undgå opslag til siderne i den underliggende tabel. For eksempel:

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

Med det ville vi forvente, at EXPLAIN viser "Using index".

For den korrelerede underforespørgsel ønsker vi et indeks med ledende kolonner som denne:

... ON cdr_records (originalCalledPartyNumber,dateTimeOrigination)

Jeg anbefaler stærkt, at du ser på outputtet fra EXPLAIN for at se, hvilke indekser MySQL bruger til forespørgslen.




  1. PostgreSQL:er det muligt at give brugerdefineret navn til PRIMÆR NØGLE eller UNIK?

  2. Sådan bruger du en fremmednøgle, når du forespørger fra to tabeller

  3. Crystal Reports vs. Microsoft SQL Server Reporting Services

  4. Hvordan kan jeg se, om en database er af høj kvalitet?