SQL CONVERT_IMPLICIT и скорость запроса

Босс запросил соединение таблицы TranGLC с нашей таблицей Invoiced. Таблица транзакций настраивается таким образом, чтобы ключевые поля представляли собой поля типа varchar, помеченные как Key1, Key2 и т. Д., С определителем для каждой записи в зависимости от того, к какой таблице присоединяется строка. Таким образом, TranGLC.RelatedTo = 'InvcDtl', Key1 и Key2 - это номер счета-фактуры и номер строки (хранятся как Ints в других таблицах). Это может быть одной из многих вещей.

Сам запрос выполнялся примерно за 9 секунд, но, когда босс добавил "Где OrderNumber = XXXXXX", который должен возвращать меньше записей, для его выполнения потребовалось 48 секунд. Странный. Он принес его мне и, взглянув на план выполнения, я начал играть и обнаружил, что TranGLC неявно конвертирует Key1 и Key2 в int, чтобы соответствовать таблице счетов.

Я попытался явным образом преобразовать InvoiceNumber и Line в поля varchar и BAM! Пробежал меньше секунды. ех.

Inner Join InvoiceDtl on TGLC.Key1 = convert(varchar(25), InvoiceDtl.InvoiceNum) and.....

План выполнения другой, но я боюсь, что именно здесь мои знания о таких вещах превращаются в догадки. Мне интересно, почему это так и как это так сильно влияет на производительность. Моя теория состоит в том, что, поскольку таблица TranGLC содержит SO гораздо больше записей (многие из которых не могут быть преобразованы в целые числа в любом случае), что неявное преобразование пытается (и во многих случаях не удается) преобразовать сначала целые столбцы TranGLC, а затем присоединяйте int к int Vs, занимая значительно меньше полей, без проблем конвертируя в varchars, а затем присоединяя varchar к varchar.

У кого-нибудь есть подробное объяснение? Запрос к контексту:

select 
            [TranGLC].[GLAccount] as [TranGLC_GLAccount],
            [InvcDtl].[InvoiceNum] as [InvcDtl_InvoiceNum],
            [InvcDtl].[OrderNum] as [InvcDtl_OrderNum],
            (SUM(TranGLC.CreditAmount)) as [Calculated_GROSS],
            (SUM(TranGLC.DebitAmount)) as [Calculated_DISCOUNT],
            (SUM(TranGLC.CreditAmount)-SUM(TranGLC.DebitAmount)) as [Calculated_NET]
from Erp.TranGLC as TranGLC
inner join Erp.InvcDtl as InvcDtl on 
            TranGLC.Company = InvcDtl.Company
            and TranGLC.Key1 = convert(varchar(25),InvcDtl.InvoiceNum)
            and TranGLC.Key2 = convert(varchar(4),Invcdtl.InvoiceLine)
            and TranGLC.RelatedToFile = 'InvcDtl'

where (TranGLC.TranDate >= '1-1-2016'  and TranGLC.TranDate <= convert(date, getdate()) and InvcDtl.OrderNum = 123456)
group by [TranGLC].[GLAccount],
            [InvcDtl].[InvoiceNum],
            [InvcDtl].[OrderNum]

WithConvert

WithoutConvert

0 ответов

Другие вопросы по тегам