如何优化此SQL查询? (Solarwinds Orion)

时间:2014-07-23 22:15:04

标签: sql sql-server

我对SQL很新,还在学习。我正在使用一个名为Solarwinds Orion的报告工具,我老实说不确定我编写的查询对程序有多具体,所以如果查询中的任何内容令人困惑,请告诉我,我会试着想一想如果它是特定于该计划的话。

我正在运行的查询的问题是它在运行很长时间(可能是一小时)后超时。我正在使用的数据库非常庞大。不幸的是,我真的不知道有多大,但我被告知这是巨大的。

有什么我做错了会产生巨大的性能影响吗?

SELECT  TOP 10000
Nodes.Caption                              AS NodeName,
NetflowApplicationSummary.AppName          AS Application_Name,
SUM(NetflowApplicationSummary.TotalBytes)  AS SUM_of_Bytes_Transferred,
AVG(Case OutBandwidth
    When 0 Then 0
    Else (NetflowApplicationSummary.TotalBytes/OutBandwidth) * 100
End)                                       AS TEST_PERCENT

FROM
((NetflowApplicationSummary 
  INNER JOIN Nodes ON (NetflowApplicationSummary.NodeID = Nodes.NodeID)) 
  INNER JOIN InterfaceTraffic ON (Nodes.NodeID = InterfaceTraffic.InterfaceID)) 
  INNER JOIN Interfaces ON (Nodes.NodeID = Interfaces.NodeID)

WHERE
( InterfaceTraffic.DateTime > (GetDate()-30) )
AND
(Nodes.WANCircuit = 1)

GROUP BY Nodes.Caption, NetflowApplicationSummary.AppName

编辑:我在每个表上运行COUNT(),结果如下。

SELECT COUNT(*) FROM NetflowApplicationSummary # 50671011
SELECT COUNT(*) FROM Nodes                     # 898
SELECT COUNT(*) FROM InterfaceTraffic          # 18000166
SELECT COUNT(*) FROM Interfaces                # 3938
                         # Total : 68,676,013

我真的不知道6800万件物品是不是一个庞大的数据库。

1 个答案:

答案 0 :(得分:1)

几点说明:

  1. INNER JOIN运算符是关联的,因此请删除FROM子句中的那些括号,让优化器找出最佳的连接顺序。
  2. 您可能会为每一行调用 getdate()函数中的隐含游标。将值存储在局部变量中并与之比较。
  3. 生成的SQL应如下所示:

    DECLARE @Date as datetime = getdate() - 30;
    
    SELECT  TOP 10000
    Nodes.Caption                              AS NodeName,
    NetflowApplicationSummary.AppName          AS Application_Name,
    SUM(NetflowApplicationSummary.TotalBytes)  AS SUM_of_Bytes_Transferred,
    AVG(Case OutBandwidth
        When 0 Then 0
        Else (NetflowApplicationSummary.TotalBytes/OutBandwidth) * 100
    End)                                       AS TEST_PERCENT
    
    FROM NetflowApplicationSummary 
      INNER JOIN Nodes            ON NetflowApplicationSummary.NodeID = Nodes.NodeID 
      INNER JOIN InterfaceTraffic ON Nodes.NodeID = InterfaceTraffic.InterfaceID 
      INNER JOIN Interfaces       ON Nodes.NodeID = Interfaces.NodeID
    
    WHERE InterfaceTraffic.DateTime > @Date 
      AND Nodes.WANCircuit          = 1
    
    GROUP BY Nodes.Caption, NetflowApplicationSummary.AppName
    

    此外,请确保您在 InterfaceTraffic 表上有一个索引,其前导字段为 DateTime 。如果这不存在,您可能需要支付第一次创建它的罚款。

    如果这没有帮助,那么您可能需要将执行计划发布到可以检查的位置。

    出于兴趣,还要对所有四个表执行计数()并发布结果,这样成员就可以自己评估 big 数据库的方式真的是。令人惊讶的是,有多少非技术人员认为1或10 GB数据库是巨大的,而我在工作站上轻松运行它!