sql >> データベース >  >> RDS >> Mysql

mysqlクエリ-ピーク同時呼び出しCDRデータ

    これは機能するはずですが、実際のパフォーマンスキラーです!

    SELECT
      calldate,
      MAX(concurrent)+1 AS peakcount
    FROM (
        SELECT
          DATE(a.calldate) as calldate,
          COUNT(b.uniqueid) AS concurrent
        FROM cdr AS a, cdr AS b
        WHERE  
          a.calldate BETWEEN '2013-11-08 00:00:00' AND '2013-11-13 23:59:59'
          AND (
            (a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate))
            OR (b.calldate<=a.calldate AND (UNIX_TIMESTAMP(b.calldate)+b.duration)>=UNIX_TIMESTAMP(a.calldate))
          )
          AND a.uniqueid>b.uniqueid
        GROUP BY a.uniqueid
      ) AS baseview
    GROUP BY calldate
    

    サンプルデータの正解を示します。仕組みは次のとおりです。

    • 最も内側の部分(a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate) ...)交差を計算します。一方の呼び出しの開始点がもう一方の呼び出しの開始点以降であり、その呼び出しの終了点またはその前にある場合、2つの呼び出しがオーバーラップします。
    • 呼び出しテーブルを自己結合すると、すべての重複が検出されます。
    • ただし、問題があります。自己結合では、1行目と2行目で重複が検出されますが、2行目と1行目で別の重複が検出されます。2つ以上の呼び出しが重複している場合、これを整理するのは面倒です。
    • データには数値の一意のIDが含まれているため、これを使用して、これらの重複、三重などをフィルタリングできます。これは、AND a.uniqueid>b.uniqueidによって実行されます。 セレクターとGROUP BY a.uniqueid 、最小のuniqueidを持つ呼び出しのみがすべての同時呼び出しを表示し、他の呼び出しはより少なく表​​示されます
    • MAX()の使用 これについては、外部クエリでこのレコードを除外します
    • +1が必要です ピークコール数を取得するには:2つの同時コールがあるコールは、ピークカウントが3であることを意味します

    SQLfiddle



    1. mysql:whoami?

    2. PostgreSQLのカウントクエリの最適化

    3. SQLで同じIDを持つ多くの行を連結するにはどうすればよいですか?

    4. phpとMySQLのシンプルな好き/嫌い評価システム