2014-11-19 4 views
2

У меня в следующей таблице:SQL Server 2008 R2: Производительность запросов

Пример:

Таблица:for_test

/* Create table for testing */ 
create table for_test 
(
cola varchar(10), 
colb varchar(10) 
); 

Вставка некоторых записей:

/* Inserting some data for test */ 
insert into for_test values('A101','B201'),('B201','C301'), 
          ('A101','X901'),('Z808','L707'), 
          ('N606','M505'),('O111','P222'), 
          ('R333','Z808'),('X901','Y444'), 
          ('T555','N606'),('F666','E777'), 
          ('G888','H999'),('X901','I221'), 
          ('O111','H999'),('V878','U766'), 
          ('S565','T555'),('W','Z808'),('B201','E777'); 

Создание индексов:

/*Creating indexs for columns*/ 
create index indx1 on for_test(cola); 
create index indx2 on for_test(colb); 

Примечание: Я попытаться сгруппировать связанные записи в один идентификатор группы. Например, запись A,B и B,C должна подпадать под группу 1, потому что B присутствует в обеих записях в cola для первой записи и colb для второй записи. Вы можете узнать больше, добавив некоторые записи, которые я привел выше, и, пожалуйста, запустите следующий запрос с вышеуказанными записями.

/* Query for Group the data */ 
with CTE as 
(
    select row_number() over(order by cola, colb) row_id, cola, colb 
    from for_test 
) 
, a as 
(
select s1.* 
, (select min(s2.row_id) from CTE s2 
    where (s1.cola = s2.cola or s1.colb = s2.cola 
    or s1.cola = s2.colb or s1.colb = s2.colb)) row_id2 
    from CTE s1 
) 
, b as 
(
    select m1.* 
    , (select m2.row_id2 from a m2 where m2.row_id = m1.row_id2) row_id3 
    from a m1 
) 
select dense_rank() over(order by row_id3) Group_ID,cola, colb 
from b 
order by cola,colb 

ВЫВОД:

http://sqlfiddle.com/#!3/fe60c/1

Время съемки:

Number of Records Time Taken 
-------------------------------- 
    40K    11:21 min 
    1Milion   above 3 hours 

Вопрос: Как улучшить производительность запроса?

+0

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

+0

@Greg, Yup! Выполнено с редактированием. – MAK

+0

Можете ли вы также указать, что именно вы пытаетесь выбраться из запроса? Несмотря на то, что они являются отличным инструментом, запросы CTE могут быть медленными, и лучше посмотреть на свою фактическую проблему, чтобы увидеть, есть ли другой способ. –

ответ

1

Вы сканируете свой стол четыре раза и row_number() over(order by cola, colb) делает его сортировкой по cola, colb три раза. Удалите индексы, которые у вас есть (если они не используются в другом месте) и добавьте тот, который поддерживает этот порядок, поэтому сортировка не нужна.

create index indx1 on for_test(cola, colb); 

Еще одна вещь, которую вы могли бы попробовать - это сохранить свой первый CTE во временной таблице.

create table #T 
(
    row_id int identity primary key, 
    cola varchar(10), 
    colb varchar(10) 
); 

insert into #T(cola, colb) 
select cola, colb 
from for_test 
order by cola, colb; 

create index IX_T_cola on #T(cola); 
create index IX_T_colb on #T(colb); 

А затем переписать запрос, чтобы использовать временную таблицу и объединение всех последовательностей вместо ИНЕКЕ с или отчетности, чтобы сделать возможным использовать индекс на колу и colb сделать стремится найти совпадающие строки ,

with a as 
(
    select s1.*, 
     (
     select min(s2.row_id) 
     from (
       select T.row_id 
       from #T as T 
       where s1.cola = T.cola 
       union all 
       select T.row_id 
       from #T as T 
       where s1.colb = T.cola 
       union all 
       select T.row_id 
       from #T as T 
       where s1.cola = T.colb 
       union all 
       select T.row_id 
       from #T as T 
       where s1.colb = T.colb 
      ) as s2 
     ) as row_id2 
    from #T s1 
) , 
b as 
(
    select m1.*, 
     (
     select m2.row_id2 
     from a m2 
     where m2.row_id = m1.row_id2 
     ) as row_id3 
    from a m1 
) 
select dense_rank() over(order by row_id3) as Group_ID, 
     cola, 
     colb 
from b 
order by cola, 
     colb; 
+0

Большое вам спасибо. Ты обалденный!! – MAK

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