Помогите рефакторинг SQL-запроса - PullRequest
0 голосов
/ 15 июля 2009

Ниже приведен мой SQL-запрос, который занимает более 10 минут и все еще выполняется ....

select DISTINCT Auditdata.ID,ns.ProviderMaster_ID as CDRComment 
from Auditdata AuditData 
inner join AuditMaster am 
    on am.ID=AuditData.AuditMaster_ID 
inner join HomeCircleMaster hcm 
    on hcm.Ori_CircleMaster_ID=am.CircleMaster_ID 
    and hcm.Ori_ServiceTypeMaster_ID=1 
    and hcm.Dest_ServiceTypeMaster_ID=1 
inner join NoSeriesMaster ns 
    on (ns.CircleMaster_ID=am.CircleMaster_ID 
    or ns.CircleMaster_ID=hcm.Dest_CircleMaster_ID) 
    and ns.ProviderMaster_ID<>am.ProviderMaster_ID  
    and ns.ServiceTypeMaster_ID=1 
INNER JOIN    NoSeriesMaster_Prefix PD 
    ON SUBSTRING(AuditData.CallTo, 1, CONVERT(INT, PD.PrefixLen)) = PD.PrefixNo       
    AND LEN(AuditData.CallTo) = CONVERT(VARCHAR(10), CONVERT(INT, PD.PrefixLen) + CONVERT(INT, PD.AfterPrefixLen))  
    AND PD.PrefixNo + ns.NoSeries = LEFT(AuditData.CallTo, len(ns.NoSeries) + CONVERT(INT, PD.PrefixLen))  
 where  AuditData.TATCallType is null   
    and  AuditData.AuditMaster_ID=74 
    and PrefixType='CALL'

В каждом столбце, используемом во внутреннем объединении, не определен индекс, а в столбцах, где в предложении также задан индекс ...

есть ли способ быстро выполнить запрос выше

Пожалуйста, помогите мне ...

Thanx


Дорогие друзья, я изменил мой SQL-запрос так, как следует, его выполнение все еще занимает много времени для 15000000

модифицированные SQL-запросы выглядят следующим образом:

select DISTINCT Auditdata.ID,ns.ProviderMaster_ID as CDRComment from Auditdata AuditData inner join AuditMaster am on am.ID=AuditData.AuditMaster_ID inner join HomeCircleMaster hcm on hcm.Ori_CircleMaster_ID=am.CircleMaster_ID and hcm.Ori_ServiceTypeMaster_ID=1 and hcm.Dest_ServiceTypeMaster_ID=1 inner join NoSeriesMaster ns on (ns.CircleMaster_ID=am.CircleMaster_ID or ns.CircleMaster_ID=hcm.Dest_CircleMaster_ID) and ns.ProviderMaster_ID<>am.ProviderMaster_ID and ns.ServiceTypeMaster_ID=1 INNER JOIN NoSeriesMaster_Prefix PD ON Auditdata.callto like PD.PrefixNo + '%' AND AuditData.CallTolen = PD.PrefixLen + PD.AfterPrefixLen AND PD.PrefixNo + ns.NoSeries = LEFT(AuditData.CallTo, NoSeriesLen + PD.PrefixLen)
where AuditData.TATCallType is null and AuditData.AuditMaster_ID=74 and PrefixType='CALL' 

Теперь, что я могу сделать ??

Дорогой друг

мой запрос занимает много раз, потому что ниже часть кода NoSeriesMaster содержит 4000 строк и Auditdata 15000000 строк с внутренним объединением каждой записи столбцов callto в AuditData, сопоставленной с Noseriesmaster

INNER JOIN NoSeriesMaster_Prefix PD
ON SUBSTRING (AuditData.CallTo, 1, CONVERT (INT, PD.PrefixLen)) = PD.PrefixNo
AND LEN (AuditData.CallTo) = CONVERT (VARCHAR (10), CONVERT (INT, PD.PrefixLen) + CONVERT (INT, PD.AfterPrefixLen))
AND PD.PrefixNo + ns.NoSeries = LEFT (AuditData.CallTo, len (ns.NoSeries) + CONVERT (INT, PD.PrefixLen))
где AuditData.TATCallType имеет значение null, а AuditData.AuditMaster_ID = 74 и PrefixType = 'CALL'

Ответы [ 4 ]

3 голосов
/ 15 июля 2009

Сложно сказать, что является причиной этого, но может помочь следующее:

  • Выполнение таких преобразований, как SUBSTRING, CONVERT, LEFT и т. Д. Для значений в соединениях, приведет к снижению производительности, поскольку это означает, что SQL Server не может эффективно использовать свои индексы. Возможно, вы захотите посмотреть на извлечение столбцов, для которых необходимо выполнить этот тип преобразования, в отдельные столбцы и индексировать их.

  • Субоптимальные индексы - кроме тех, которые вы не можете использовать из-за всех преобразований, правильно ли проиндексированы другие столбцы, к которым вы присоединяетесь? Посмотрите на мастера настройки индекса, который может вам помочь.

2 голосов
/ 15 июля 2009

Что вы можете сделать, это использовать представление «План выполнения» в SQL Server Management Studio при выполнении этого запроса. Он покажет, на какие шаги SQL тратит больше всего времени на обработку вашего запроса. Отсюда, по крайней мере, есть идея, где должна происходить оптимизация.

План выполнения также представлен в приложении SQL Server Management Studio Express.

Просто откройте новое окно запроса, нажмите «Запрос»> «Показать примерный план выполнения» и выполните запрос. План выполнения появится после завершения запроса.

0 голосов
/ 15 июля 2009

План выполнения скажет вам точно, что занимает больше всего времени.

Вероятно, это последнее объединение, которое вызывает больше всего работы. Поскольку вы сравниваете вычисленные значения, база данных не может использовать индексы для поиска.

Я вижу, что вы делаете CONVERT(VARCHAR(10), ...) для числового значения, но затем сравниваете его с числом. Вы должны иметь возможность просто удалить это преобразование.

Вы конвертируете поле PrefixLen в число в нескольких местах. Действительно ли это поле является текстовым полем, и если это так, можете ли вы преобразовать его в числовое поле?

Вы сравниваете первую часть AuditData с PrefixNo, затем вы сравниваете немного больше поля с PrefixNo + NoSeries. Если не возникает проблема со значениями «кровотечение», поскольку из-за отсутствия разделителя (например, «01» + «23» = «0» + «123») вы можете просто удалить первое сравнение.

0 голосов
/ 15 июля 2009

И еще одно - вы можете попытаться поместить некоторые условия из WHERE в JOIN:

from Auditdata AuditData 
inner join AuditMaster am 
    on am.ID=AuditData.AuditMaster_ID AND AuditData.TATCallType is null   
    and  AuditData.AuditMaster_ID=74 

но я думаю, что Оптимизатор запросов должен это сделать.

В любом случае, вам сначала нужно просмотреть план выполнения.

...