需要帮助优化SQL查询

时间:2011-07-21 15:05:20

标签: sql sql-server linq-to-sql

我绝对不是DBA,不幸的是我们没有DBA在我们公司内部进行咨询。我想知道是否有人可以通过更改查询本身或向数据库添加索引来提供有关如何改进此查询的建议。

查看查询的执行计划,似乎外连接正在查询查询。此查询仅返回350k结果,但完成时间大约需要30秒。我对DB的了解不多,但我认为这不好?也许我错了?

任何建议都将不胜感激。提前致谢。

作为旁注,这显然是由ORM而不是我直接创建的。我们正在使用Linq-to-SQL。

SELECT 
    [t12].[value] AS [DiscoveryEnabled], 
    [t12].[value2] AS [isConnected], 
    [t12].[Interface], 
    [t12].[Description] AS [InterfaceDescription], 
    [t12].[value3] AS [Duplex], 
    [t12].[value4] AS [IsEnabled], 
    [t12].[value5] AS [Host], 
    [t12].[value6] AS [HostIP], 
    [t12].[value7] AS [MAC], 
    [t12].[value8] AS [MACadded], 
    [t12].[value9] AS [PortFast], 
    [t12].[value10] AS [PortSecurity], 
    [t12].[value11] AS [ShortHost], 
    [t12].[value12] AS [SNMPlink], 
    [t12].[value13] AS [Speed], 
    [t12].[value14] AS [InterfaceStatus], 
    [t12].[InterfaceType], 
    [t12].[value15] AS [IsUserPort], 
    [t12].[value16] AS [VLAN], 
    [t12].[value17] AS [Code], 
    [t12].[Description2] AS [Description], 
    [t12].[Host] AS [DeviceName], 
    [t12].[NET_OUID], 
    [t12].[DisplayName] AS [Net_OU], 
    [t12].[Enclave]
FROM (
    SELECT 
        [t1].[DiscoveryEnabled] AS [value], 
        [t1].[IsConnected] AS [value2], 
        [t0].[Interface], 
        [t0].[Description], 
        [t2].[Duplex] AS [value3], 
        [t0].[IsEnabled] AS [value4], 
        [t3].[Host] AS [value5], 
        [t6].[Address] AS [value6], 
        [t3].[MAC] AS [value7], 
        [t3].[MACadded] AS [value8], 
        [t2].[PortFast] AS [value9], 
        [t2].[PortSecurity] AS [value10], 
        [t4].[Host] AS [value11], 
        [t0].[SNMPlink] AS [value12], 
        [t2].[Speed] AS [value13], 
        [t2].[InterfaceStatus] AS [value14], 
        [t8].[InterfaceType], 
        [t0].[IsUserPort] AS [value15], 
        [t2].[VLAN] AS [value16], 
        [t9].[Code] AS [value17], 
        [t9].[Description] AS [Description2], 
        [t7].[Host], [t7].[NET_OUID], 
        [t10].[DisplayName], 
        [t11].[Enclave], 
        [t7].[Decommissioned]
    FROM [dbo].[IDB_Interface] AS [t0]
        LEFT OUTER JOIN [dbo].[IDB_InterfaceLayer2] AS [t1] ON [t0].[IDB_Interface_ID] = [t1].[IDB_Interface_ID]
        LEFT OUTER JOIN [dbo].[IDB_LANinterface] AS [t2] ON [t1].[IDB_InterfaceLayer2_ID] = [t2].[IDB_InterfaceLayer2_ID]
        LEFT OUTER JOIN [dbo].[IDB_Host] AS [t3] ON [t2].[IDB_LANinterface_ID] = [t3].[IDB_LANinterface_ID]
        LEFT OUTER JOIN [dbo].[IDB_Infrastructure] AS [t4] ON [t0].[IDB_Interface_ID] = [t4].[IDB_Interface_ID]
        LEFT OUTER JOIN [dbo].[IDB_AddressMapIPv4] AS [t5] ON [t3].[IDB_AddressMapIPv4_ID] = ([t5].[IDB_AddressMapIPv4_ID])
        LEFT OUTER JOIN [dbo].[IDB_AddressIPv4] AS [t6] ON [t5].[IDB_AddressIPv4_ID] = [t6].[IDB_AddressIPv4_ID]
        INNER JOIN [dbo].[ART_Asset] AS [t7] ON [t7].[ART_Asset_ID] = [t0].[ART_Asset_ID]
        LEFT OUTER JOIN [dbo].[NSD_InterfaceType] AS [t8] ON [t8].[NSD_InterfaceTypeID] = [t0].[NSD_InterfaceTypeID]
        INNER JOIN [dbo].[NSD_InterfaceCode] AS [t9] ON [t9].[NSD_InterfaceCodeID] = [t0].[NSD_InterfaceCodeID]
        INNER JOIN [dbo].[NET_OU] AS [t10] ON [t10].[NET_OUID] = [t7].[NET_OUID]
        INNER JOIN [dbo].[NET_Enclave] AS [t11] ON [t11].[NET_EnclaveID] = [t10].[NET_EnclaveID]
    ) AS [t12]
WHERE ([t12].[Enclave] = 'USMC') AND (NOT ([t12].[Decommissioned] = 1))

LINQ-TO-SQL查询:

return from t in db.IDB_Interfaces
             join v in db.IDB_InterfaceLayer3s on t.IDB_Interface_ID equals v.IDB_Interface_ID
             join u in db.ART_Assets on t.ART_Asset_ID equals u.ART_Asset_ID
             join c in db.NET_OUs on u.NET_OUID equals c.NET_OUID
             join w in
               (from d in db.IDB_InterfaceIPv4s
                select new { d.IDB_InterfaceIPv4_ID, d.IDB_InterfaceLayer3_ID, d.IDB_AddressMapIPv4_ID, d.IDB_AddressMapIPv4.IDB_AddressIPv4.Address })
             on v.IDB_InterfaceLayer3_ID equals w.IDB_InterfaceLayer3_ID
             join h in db.NET_Enclaves on c.NET_EnclaveID equals h.NET_EnclaveID into enclaveLeftJoin
             from i in enclaveLeftJoin.DefaultIfEmpty()
             join m in
               (from z in db.IDB_StandbyIPv4s
                select new
                {
                  z.IDB_InterfaceIPv4_ID,
                  z.IDB_AddressMapIPv4_ID,
                  z.IDB_AddressMapIPv4.IDB_AddressIPv4.Address,
                  z.Preempt,
                  z.Priority
                })
             on w.IDB_InterfaceIPv4_ID equals m.IDB_InterfaceIPv4_ID into standbyLeftJoin
             from k in standbyLeftJoin.DefaultIfEmpty()
             where t.ART_Asset.Decommissioned == false
             select new NetIDBGridDataResults
             {
               DeviceName = u.Host,
               Host = u.Host,
               Interface = t.Interface,
               IPAddress = w.Address,
               ACLIn = v.InboundACL,
               ACLOut = v.OutboundACL,
               VirtualAddress = k.Address,
               VirtualPriority = k.Priority,
               VirtualPreempt = k.Preempt,
               InterfaceDescription = t.Description,
               Enclave = i.Enclave
             };

2 个答案:

答案 0 :(得分:1)

作为一项规则(这是非常一般的),您需要一个索引:

  • JOIN字段(双方)
  • 常见WHERE过滤字段
  • 可能是您汇总的字段

对于此查询,请先检查JOIN条件。任何一个失踪都会强制进行表格扫描,这是一个很大的打击。

答案 1 :(得分:0)

  

查看查询的执行计划,似乎外连接正在查询查询。   此查询仅返回350k结果,但完成时间大约需要30秒。我不知道   很多关于DB的,但我认为这不好?也许我错了?

一个男人必须做一个法术力必须要做的事。

连接可能会杀死你,但是当你需要它们时,你需要它们。有些任务需要很长时间。

  • 确保您拥有所需的所有指数。
  • 确保你的sql server不是一个悲伤的笑话硬件。 所有你能做的。

我打赌有人对SQL没有任何线索,需要了解指数的力量。