7

日時の範囲を調べて、特定の呼び出しが行われた時点での同時呼び出しの数を計算しようとしています。クエリは機能しますが、95,000 レコードしか実行するのに 10 分もかかりません。これは長すぎます。最適化のアイデアはありますか?

SELECT r.*,
       rr.ChannelsActive  'ChannelsActive'
FROM #rg r
OUTER APPLY
(
      SELECT SUM(1) AS ChannelsActive
      FROM #rg r_inner 
      WHERE 
      (
             r_inner.CallStart BETWEEN r.CallStart AND r.CallEnd 
            OR r_inner.CallEnd BETWEEN r.CallStart AND r.CallEnd
            OR r.CallStart BETWEEN r_inner.CallStart AND r_inner.CallEnd 
            OR r.CallEnd BETWEEN r_inner.CallStart AND r_inner.CallEnd

      )
 ) rr

サンプルデータ

CREATE TABLE #rg
  (
     CallStart DATETIME,
     CallEnd   DATETIME
  )

CREATE INDEX ix1
  ON #rg(CallStart, CallEnd)

CREATE INDEX ix2
  ON #rg(CallEnd, CallStart);

WITH T(N, R)
     AS (SELECT TOP (95000) ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS RN,
                            ABS(120 + 30 * SQRT(-2 * LOG(ABS(CAST(CAST(CRYPT_GEN_RANDOM(8) AS BIGINT) AS FLOAT) / 9223372036854775807))) * COS(2 * PI() * ABS(CAST(CAST(CRYPT_GEN_RANDOM(8) AS BIGINT) AS FLOAT) / 9223372036854775807)))
         FROM   sys.all_objects o1,
                sys.all_objects o2)
INSERT INTO #rg
SELECT DATEADD(SECOND, N, GETDATE()),
       DATEADD(SECOND, N + R, GETDATE())
FROM   T 
4

2 に答える 2

1

このような SQL を使用して、開始/終了イベントのリストを取得します...

Select CallStart, 1 As CallCount From #rg
Union All
Select CallEnd, -1 From #rg
Order By CallStart

...次に、これを単純な実行中の合計の問題として扱います。これは、SQL Server のバージョンに応じて異なる方法で解決されるか、オプションである場合はコードで簡単に対処できます。

于 2013-07-03T19:28:44.437 に答える