2

私はかなりうまく機能するクレイジーなステートメントを書きましたが、 2回INSERT/SELECTの使用を避けることができれば、もう少し調整できると思います。LEN([stats].[dbo].[Domain].[DomainName])現在、実行には 20 秒かかります。これらのLENセクションをテスト用の実際の数値に置き換えると、文字通り 1 秒かかります。したがって、私の希望です!

それを変数に入れる方法について頭を悩ませてきたので、それを2回使用できますが、パフォーマンスは1回しかヒットしません。私はその価値のために SQL Server 2008 R2 を使用しています。

どうもありがとう!

INSERT INTO [stats].[dbo].[5MinStats] (Qty, MsgRequest, MsgRecType, MsgDateTime, DomainID)
   SELECT
      COUNT([stats].[dbo].[RawMsgLog].[MsgRequest]) AS Qty, 
      [stats].[dbo].[RawMsgLog].[MsgRequest], 
      [stats].[dbo].[RawMsgLog].[MsgRecType], 
      DATEADD(minute, DATEDIFF(minute, 0, [stats].[dbo].[RawMsgLog].[MsgDateTime])/ 5 * 5, 0) AS MsgDateTime, 
      [stats].[dbo].[Domain].[DomainID] 
   FROM 
      [stats].[dbo].[RawMsgLog], [stats].[dbo].[Domain]
   WHERE 
      RIGHT([stats].[dbo].[Domain].[DomainName], LEN([stats].[dbo].[Domain].[DomainName])) = RIGHT([stats].[dbo].[RawMsgLog].[MsgRequest], LEN([stats].[dbo].[Domain].[DomainName]))
      AND [stats].[dbo].[RawMsgLog].[switch] = 1
   GROUP BY 
      [stats].[dbo].[RawMsgLog].[MsgRequest], 
      [stats].[dbo].[RawMsgLog].[MsgRecType], 
      DATEADD(minute, DATEDIFF(minute, 0, [stats].[dbo].[RawMsgLog].[MsgDateTime]) / 5 * 5, 0), 
      [stats].[dbo].[Domain].[DomainID]
   ORDER BY 
      MsgDateTime ASC
4

3 に答える 3

3

WHEREを次のように変更します。

WHERE stats.dbo.Domain.DomainName LIKE '%' + stats.dbo.RawMsgLog.MsgRequest

RIGHT()これにより、関数と関数が回避LEN()され、クエリで利用可能なインデックスを使用できるようになります...インデックス付きの列に関数を適用すると、それらが難読化され、代わりにスキャンが使用されます。

また、他にもいくつか変更を加えます...

  1. テーブルにエイリアスを設定します。
  2. []必要がなければ使わない...
  3. 明示的に使用しJOINます。

これにより、次のクエリが得られます。

INSERT INTO stats.dbo.5MinStats (
    Qty, 
    MsgRequest, 
    MsgRecType, 
    MsgDateTime, 
    DomainID
)
SELECT 
    COUNT(rml.MsgRequest) as Qty, 
    rml.MsgRequest, 
    rml.MsgRecType, 
    DATEADD(minute, 
      DATEDIFF(minute, 0, rml.MsgDateTime)/ 5 * 5, 0) as MsgDateTime, 
    d.DomainID 
FROM 
    stats.dbo.RawMsgLog rml
    JOIN stats.dbo.Domain d
        ON d.DomainName LIKE '%' + rml.MsgRequest
WHERE rml.switch=1
GROUP BY 
    rml.MsgRequest, 
    rml.MsgRecType, 
    dateadd(minute, datediff(minute, 0, rml.MsgDateTime)/ 5 * 5, 0), 
    d.DomainID
ORDER BY MsgDateTime ASC
于 2013-03-25T22:40:15.060 に答える
0

CHARINDEXこれを高速化するために使用できます:

WHERE CHARINDEX([stats].[dbo].[Domain].[DomainName], [stats].[dbo].[RawMsgLog].[MsgRequest]) > 0

DomainName値が列のどこかにある場合、これは true を返しMsgRequestます。

于 2013-03-25T22:46:09.593 に答える
0

In the first half of your condition, you do a "right" with the length of the substring being the length of the substring being the length of the field自体 (ie right(field, len(field)). これを削除して、フィールドのみを使用できます次に、比較をワイルドカード テキストにすることができます。

WHERE stats.dbo.RawMsgLog.MsgRequest like '%' + stats.dbo.Domain.DomainName

この部分文字列比較も使用できますが、遅くなると思います。

right(stats.dbo.RawMsgLog.MsgRequest, LEN(stats.dbo.Domain.DomainName)) = stats.dbo.Domain.DomainName
于 2013-03-25T22:59:08.240 に答える