Нужна помощь в оптимизации этого запроса tSQL - PullRequest
0 голосов
/ 21 июля 2011

Я определенно не администратор, и, к сожалению, у нас нет администратора, чтобы проконсультироваться в нашей компании. Мне было интересно, может ли кто-нибудь дать мне рекомендацию о том, как улучшить этот запрос, изменив сам запрос или добавив индексы в базу данных.

Глядя на план выполнения запроса, кажется, что внешние объединения убивают запрос. Этот запрос возвращает только 350 тыс. Результатов, но для его завершения требуется почти 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 ]

1 голос
/ 21 июля 2011

Как правило (и это очень общее), вы хотите индекс для:

  • JOIN поля (с обеих сторон)
  • Общие WHERE поля фильтра
  • Возможно, поля, которые вы собираете

Для этого запроса начните с проверки критериев JOIN. Любой из этих пропавших без вести вызовет сканирование таблицы, что является большим успехом.

0 голосов
/ 21 июля 2011

Глядя на план выполнения запроса, кажется, что внешние объединения убивают запрос.Этот запрос возвращает только 350 тыс. Результатов, но для его завершения требуется почти 30 секунд.Я не знаю много о DB, но я не думаю, что это хорошо?Возможно, я ошибаюсь?

Человек должен делать то, что нужно делать мане.

Соединения могут вас убить, но когда они вам нужны, ТЫ НУЖНА ИХ.Некоторые задачи занимают много времени.

  • Убедитесь, что у вас есть все нужные вам индексы.
  • Убедитесь, что ваш sql-сервер не является грустной аппаратной шуткой.Все, что вы можете сделать.

Бьюсь об заклад, кто-то не имеет ни малейшего представления о SQL и нуждается в понимании силы индексов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...