如何在我的SELECT(T-SQL)中使用变量

时间:2013-03-25 22:37:31

标签: sql sql-server performance tsql

我写了一个非常好的疯狂INSERT/SELECT语句,除了我认为如果我可以避免两次使用LEN([stats].[dbo].[Domain].[DomainName]),它可以调整得更多。现在它需要20秒才能运行,如果我用测试的实际数字替换这些LEN部分,它实际需要一秒钟,因此我的希望!

我一直在努力研究如何将它变成一个变量,所以我可以使用它两次,但只有一个性能命中。我正在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

3 个答案:

答案 0 :(得分:3)

将您的WHERE更改为以下内容:

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

这避免了RIGHT()LEN()函数,并允许您的查询使用任何可用的索引...将函数应用于索引列将对它们进行模糊处理并导致使用扫描。< / p>

我还会做一些其他改变......

  1. 别名你的桌子。
  2. 如果您不需要...... {/ li>,请不要使用[]
  3. 使用明确的JOIN
  4. 这将为您提供以下查询:

    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
    

答案 1 :(得分:0)

您可以使用CHARINDEX来加快速度:

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

如果在DomainName列中的任何位置找到MsgRequest中的值,则返回true。

答案 2 :(得分:0)

在你的条件的前半部分,你做一个“右”,子串的长度与字段本身的长度相同(即右(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