sql >> Databáze >  >> RDS >> Mysql

Filtrování sady výsledků dotazu MySQL pro získání více výskytů v určitém časovém období

Pokud chceme odfiltrovat řádky, kde za posledních 60 sekund nebyly alespoň čtyři předchozí řádky, za předpokladu, že dateTimeOrigination je celočíselný typ, 32bitové časové razítko ve stylu unixu, můžeme udělat něco takového:

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

POZNÁMKA:Kvůli výkonu preferujeme mít predikáty na holých sloupcích.

S formulářem jako je tento, se sloupcem zabaleným do výrazu:

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

MySQL vyhodnotí funkci pro každého řádku v tabulce a poté porovnejte návrat z funkce s literálem.

S formulářem jako je tento:

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

MySQL vyhodnotí výrazy na pravé straně jedna čas, jako doslova . Což umožňuje MySQL efektivně využívat operaci skenování rozsahu na vhodném indexu.

NÁSLEDOVAT

Pro nejlepší výkon vnějšího dotazu by nejlepším indexem byl pravděpodobně index s úvodním sloupcem dateTimeOrigination, pokud možno obsahující

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

Pro nejlepší výkon použijte krycí index, abyste se vyhnuli vyhledávání stránek v podkladové tabulce. Například:

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

S tím bychom očekávali, že EXPLAIN zobrazí "Using index".

Pro korelovaný poddotaz bychom chtěli index s úvodními sloupci, jako je tento:

... ON cdr_records (originalCalledPartyNumber,dateTimeOrigination)

Důrazně doporučuji podívat se na výstup z EXPLAIN a zjistit, které indexy MySQL používá pro dotaz.




  1. mysql count nefunguje správně?

  2. MySql:nastavte proměnnou se seznamem

  3. Jak TO_DAYS() funguje v MariaDB

  4. ladit dotaz mysqli pomocí nebo zemřít mysqli_error