2016-03-10 2 views
0

Этот запрос, показанный ниже, занимает около 2 часов, и я хочу сократить время выполнения этого запроса. Любая помощь будет действительно полезна для меня.SQL Join занимает слишком много времени для запуска

В настоящее время:

If Exists (Select 1         
      From PRODUCTS prd         
      Join STORE_RANGE_GRP_MATCH srg On prd.Store_Range_Grp_Id = srg.Orig_Store_Range_Grp_ID   
              And srg.Match_Flag = 'Y' 
              And prd.Range_Event_Id = srg.LAR_Range_Event_Id 
      Where srg.Range_Event_Id Not IN (Select distinct Range_Event_Id 
              From Last_Authorised_Range) 
     )  

Я попытался заменить пункт Not IN на Not Exists и Left join, но не повезло в исполнении во время выполнения.

То, что я использовал:

If Exists( Select top 1 *       
     From PRODUCTS prd        
     Join STORE srg        
     On prd.Store_Range_Grp_Id = srg.Orig_Store_Range_Grp_ID         
     And srg.Match_Flag = 'Y'         
     And prd.Range_Event_Id = srg.LAR_Range_Event_Id 
and   srg.Range_Event_Id ='45655'   



Where NOT EXISTS (Select top 1 *         
     From Last_Authorised_Range where Range_Event_Id=srg.Range_Event_Id)        
) 

Product таблица содержит 432837 записей и Store таблицы также имеет почти такое же количество записей. Эта таблица я создаю в самой хранимой процедуре, а затем удаляю ее в конце хранимой процедуры.

Create Table PRODUCTS         
(        
    Range_Event_Id int,         
    Store_Range_Grp_Id int,         
    Ranging_Prod_No nvarchar(14) collate database_default, 
    Space_Break_Code nchar(1) collate database_default 
)      

Create Clustered Index Idx_tmpLAR_PRODUCTS 
    ON PRODUCTS (Range_Event_Id, Ranging_Prod_No, Store_Range_Grp_Id, Space_Break_Code) 

Должен ли я использовать не кластерный индекс по этой таблице или то, что все я могу сделать, чтобы уменьшить время выполнения? Заранее спасибо

+0

Где находится «ПЕРВЫЙ КЛЮЧ» в «ПРОДУКТАХ»? – Lankymart

+0

поместите результат 'Выбрать выделенный Range_Event_Id From Last_Authorised_Range' в переменной таблицы и использовать его не существует. – artm

+1

Удалите 'top 1' и/или' distinct' clauses - 'exists()' и 'in()' работают лучше без них. Вы можете использовать 'select *' вместо 'select 1' - гораздо лучше читаемость; Оптимизатор SQL генерирует для них идентичные планы запросов. Создавайте индексы во всех ID-полях. – Arvo

ответ

0

Сначала вам не нужны top 1 или distinct в exists и in подзапросы. Но это не должно влиять на производительность.

Это запрос, слегка перестроены, так что я могу понять это лучше:

Select 1       
From PRODUCTS prd Join 
    STORE srg        
    On prd.Store_Range_Grp_Id = srg.Orig_Store_Range_Grp_ID and 
     prd.Range_Event_Id = srg.LAR_Range_Event_Id        
Where srg.Match_Flag = 'Y'         
     srg.Range_Event_Id = 45655 and 
Where NOT EXISTS (Select 1         
        From Last_Authorised_Range lar 
        where lar.Range_Event_Id = srg.Range_Event_Id)        
       ) 

ли к сведению, что я удалил двойные кавычки 45655. Я полагаю, что этот столбец фактически является числом. Если да, не путайте себя и оптимизатор, используя строку для сравнения.

Затем попробуйте индексы. Я думаю, что лучшие показатели являются:

  • store(Range_Event_Id, Match_Flag, Orig_Store_Range_Grp_ID, LAR_Range_Event_Id)
  • products(Store_Range_Grp_Id, Range_Event_Id) (или какой-либо индекс, кластерный или иначе, которая начинается с этих двух столбцов в любом порядке)
  • Last_Authorised_Range(Range_Event_Id)

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

+0

Я также использовал индексы и реализовал левое внешнее соединение, удалив Not In Clause, но для выполнения все еще требуется 2 часа. –

+0

В настоящее время я использую кластерный индекс во всех таблицах, которые используются, должен ли я менять кластеризованный индекс на некластеризованный? Если да, то почему ??? –

+0

@SumitDwivedi. , , Вы пробовали индексы, упомянутые в этом ответе? –

Смежные вопросы