Повышение производительности запросов в таблице 300 миллионов строк - PullRequest
0 голосов
/ 14 ноября 2018

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

select xa.*, s.idA 
from tableA s 
inner join tableB xa on s.idA = xa.idB
where xa.type = 'type_A'
  • TableA = 80 миллионов строк
  • TableB = 340 миллионов строк

TableA имеет некластеризованный индекс на idA и TableB некластеризованный индекс на idB.План выполнения использует индекс TableA и выполняет полное сканирование таблицы для TableB, что занимает 98% усилий.Я попытался создать некластеризованный индекс для TableB, для столбца idB, включая столбец Type.Мне пришлось убить запрос на создание через час, потому что он был приостановлен с типом ожидания CXPACKET.Возможно, он ждал, чтобы прочитать все данные, но мои потоки служб SSIS не могут позволить себе тратить ресурсы на такое большое количество времени.Затем я попытался создать кластеризованный индекс для типа столбца tableB, который, как я думал, займет меньше времени.План состоял в том, чтобы изменить запрос с помощью cte, например:

;with tmp as 
(
     select * 
     from tableB 
     where type = 'Type_A'
)
select xa.*, s.idA 
from tableA s 
inner join tmp xa on s.idA = xa.idB

. При использовании этого запроса у меня будет только 200 тыс. Строк в таблице tmp, и я буду избегать полного сканирования таблицы, чтобы отфильтровать tableB, используя все доступные индексыпоэтому я думаю, что это значительно улучшит скорость

Однако мне пришлось убить запрос на создание, поскольку он занимал более 1 часа (снова приостановлено, снова CXPACKET).Итак, мой вопрос: возможно ли ускорить процесс создания индекса?Можно ли оценить время, необходимое для создания индекса?

1 Ответ

0 голосов
/ 14 ноября 2018

Перемещение критериев в подзапрос (CTE) не является решением. Вы должны использовать SQL, чтобы сообщить СУБД, что нужно получить, а не как его получить. Задача СУБД - найти оптимальный план. Поэтому напишите запрос как можно более читабельным и помогите СУБД, указав соответствующие индексы.

У вас должны быть следующие индексы для запроса:

create index idx1 on tableB ( type, idB ); -- to find B quickly and have the ID ready for the join
create index idx2 on tableA ( idA );

(выглядит странно, что вы присоединяетесь к idA = idB, но я думаю, что это только в примере, верно?)

...