2013-12-18 3 views
1

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

select top 1 
     a 
    , b 
    , c 
from table 
where x = 1 
and y = 2 
and z > getdate() 
order by 
     b desc 
    , c desc 

и индекс, как:

create index idx_ on table 
(
    x 
    , y 
    , z 
    , b 
    , c 
) 
include (a) 

Моя проблема заключается в том, что после фильтров я оставил с около 6 млн записей. И SQL Server также не будет сортировать на основе индекса, и из-за этого времена для этого запроса очень большие.

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

select (0%) <- TOP N SORT (94%) <= INDEX SEEK (6%) 

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

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

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

select 
* 
from #tmp_xs xs 
outer apply 
    (select top 1 
     a 
     , b 
     , c 
    from table 
    where x = xs.rel_x 
    and y = 2 
    and z > getdate() 
    order by 
     b desc 
     , c desc) xs_res 

По какой-то причине для вышеупомянутого сервера SQL-запрос будет использовать только индекс фильтрации. Если внутренний запрос помещен внутри встроенной функции, результат будет схожим. Если я не помещаю его в встроенную функцию, оба индекса работают, и запрос выполняется очень быстро.

+0

Этот индекс может использоваться для процесса выбора - поскольку в нем запрашиваются 'x, y, z'. Он ** не может использоваться ** для сортировки, так как столбцы сортировки 'b' и' c' ** не ** - самые левые столбцы в этом индексе! Я предлагаю вам создавать по индексу на '(x, y, z)' для выбора, а второй - отдельный индекс на '(b, c)' для заказов –

+0

Спасибо, он работал отлично .. хотя я делаю не знаю, как пометить его как правого. –

+0

Вопрос в том, почему после того, как он был помещен внутрь внешнего, он возвращается к более раннему плану (например, выше, не используя второй индекс). –

ответ

0

Этот индекс, который у вас уже есть, может быть использован для процесса выбора - поскольку в нем есть x, y, z, которые запрашиваются как самые левые столбцы.

Его нельзя использовать для сортировки, поскольку столбцы сортировки b и c не являются самыми левыми столбцами этого индекса.

Я предлагаю вам создать индекс на (x, y, z) для выбора, а второй - отдельный индекс на (b, c) для заказа результатов.

+0

Это был хороший ответ на мой вопрос .. однако .. почему, когда он размещен внутри внешнего, он не будет использовать второй индекс? –

+1

@DumitrescuBogdan: вы не показываете * внешнее приложение *, о котором вы говорите, поэтому я действительно не могу сказать, в чем проблема .... –

+0

Хорошо, я обновил сообщение .. Я исправил его, поставив запрос внутри функции non inline table ... но мне не нравится, что я не знаю, что происходит. –

0

Запустите запрос в SSMS (SQL Server Management Studio) и попросите его подготовить план запроса. Он дает подсказки об индексах, которые могли бы помочь и на самом деле очень хороши в этом. Кроме того, @marc_s звучит разумно, но я все же попробую сначала в SSMS.

+0

Ответы на вопросы были именно тем, что я искал. На самом деле это была моя ошибка, поскольку у меня был второй индекс, но я использовал подсказку только с индексом, который я показал. QP из исходного сообщения был из SSMS. –

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