dateTimeOriginationが整数型で32ビットのUNIXスタイルのタイムスタンプであると仮定して、過去60秒以内に先行する行が4つ以上ない行を除外する場合は、次のように実行できます。
>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
注:パフォーマンスのために、裸の列に述語を設定することをお勧めします。
このようなフォームで、列を式でラップします:
WHERE FROM_UNIXTIME(r.dateTimeOrigination) LIKE '2016-05-20%'
MySQLはすべての関数を評価します テーブルの行を入力し、関数からの戻り値をリテラルと比較します。
このようなフォームで:
WHERE r.dateTimeOrigination >= UNIX_TIMESTAMP('2016-05-20')
AND r.dateTimeOrigination < UNIX_TIMESTAMP('2016-05-21')
MySQLは右側の式を評価します1つ 時間、リテラル 。これにより、MySQLは適切なインデックスで範囲スキャン操作を効果的に利用できます。
フォローアップ
外部クエリのパフォーマンスを最高にするには、dateTimeOriginationの先頭に列があり、できれば
を含むインデックスが最適なインデックスになる可能性があります。... ON cdr_records (dateTimeOrigination
,callingPartyNumber,originalCalledPartyNumber,finalCalledPartyNumber)
最高のパフォーマンスを得るには、基になるテーブルのページへのルックアップを回避するためのカバーインデックス。例:
... ON cdr_records (dateTimeOrigination
,callingPartyNumber,originalCalledPartyNumber,finalCalledPartyNumber
,duration,origDeviceName,destDeviceName)
これで、EXPLAINに「インデックスの使用」が表示されると予想されます。
相関サブクエリの場合、次のような先頭の列を持つインデックスが必要です。
... ON cdr_records (originalCalledPartyNumber,dateTimeOrigination)
EXPLAINからの出力を見て、MySQLがクエリに使用しているインデックスを確認することを強くお勧めします。