2009-07-15 1 views
0

Ниже мой SQL-запрос, который занимает более 10 минут, и до сих пор работает ....Помощь рефакторинга в 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 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 Query как следовать его еще занять много времени, чтобы выполнить Против 15000000

модифицированном SQL Query следующим образом:

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
И LEN (AuditData.CallTo) = C ONVERT (VARCHAR (10), CONVERT (INT, PD.PrefixLen) + CONVERT (INT, PD.AfterPrefixLen))
И PD.PrefixNo + ns.NoSeries = LEFT (AuditData.CallTo, len (ns.NoSeries) + CONVERT (INT, PD.PrefixLen))
где AuditData.TATCallType равна нулю и AuditData.AuditMaster_ID = 74 и PrefixType = 'ВЫЗОВ'

+0

Дорогой друг, Когда я запускаю ниже 2 запроса и время выполнения отличается ... выберите идентификатор из auditdata где подстрока (callto, 1,2) = '91' и LEN (callto) = 12 \t (Это выполнения запроса в течение 25 секунд) выберите идентификатор из auditdata, где callto как '91%»и calltolen = 12 (этот пробег запроса в 33 секунд) \t Y это различные функции в – John

ответ

3

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

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

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

+0

где положение (или присоединиться) - это его что разрушает производительность. Каждая калорация должна выполняться в каждой строке несколько раз - это можно сделать только быстрее, создав производные столбцы и индексируя их. – cjk

+1

@ck - Разве это не то, что я сказал? –

+0

ok im создает производные столбцы, а затем проверяет – John

2

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

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

Просто откройте новое окно запросов, нажмите Query> Display Approimated Plan Execution Plan и запустите запрос. После завершения запроса появится план выполнения.

+0

im using SQL Server 2000 – John

+0

Query Analyzer также имеет план выполнения, у меня его нет прямо сейчас, поэтому я не могу точно сказать, где его найти, но он действительно находится там ! – Peter

0

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

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

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

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

0

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

Это, вероятно, последнее соединение, которое вызывает наибольшую работу. Когда вы сравниваете вычисленные значения, база данных не может использовать индексы для поиска.

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

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

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