2015-03-07 2 views
1

Я работаю с SQL Server 2012. У меня есть таблица MyTable с разумным количеством индексов. Таблица имеет около 10 миллионов записей и 20 столбцов:Укажите порядок проверки ограничений в запросе SQL

Field1, Field2, ..., Field20. 

Я пишу запрос к таблице с 15 ограничений на поля:

select * 
from MyTable 
where Field1 = Value1 and Field2 = Value2 and... Field15 = Value15 

Проблема заключается в том, что если я ставлю все 15, то запрос выполняется навсегда, хотя предполагается, что он должен вернуть только около ~ 50 записей. Напротив, если я установлю все пять ограничений, запрос выполняется через пару секунд и возвращает около 300 записей (т. Е. Очень маленький набор). Поэтому довольно быстро применить к этому надмножеству те 10 фильтров, которые были оставлены: его можно применять либо на стороне C# на стороне клиента, либо быть вставленным во временную таблицу на стороне сервера.

Мой вопрос заключается в том, есть ли способ явно указать SQL Server, как и в какой последовательности применять ограничения, указанные в предложении WHERE? Например, когда SQL Server обрабатывает список ограничений, он должен сначала обработать ограничения для полей Field1, Field3 и Field7 и только затем начать применять другие фильтры к приведенному набору.

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

Спасибо за любое направление!

UPDATE: кажется, что предложение marc_s использовать CTE (Common Table Expression) - это то, что я искал.

+0

Можете ли вы указать (1), какие поля находятся в вашем предложении where (2), какие индексы находятся в таблице (3), любые разделы в таблице и (4) предоставляют план выполнения запроса всеми 15 условиями и (5) предоставить план выполнения запроса с меньшим количеством всех условий, где он работает хорошо –

+4

В разделе 'WHERE' нет возможности« устанавливать приоритеты », если вам нужно сначала убедиться, что определенные условия были проверены, вы будете необходимо выполнить подзапрос с такими условиями и обернуть его в CTE (Common Table Expression) или сохранить результаты в таблице temp, чтобы выполнить дальнейшую обработку на последующих этапах –

+2

за пределами @marc_s отличный совет, взгляните на план выполнения и статистику сервера (IO и TIME) и выяснить, какое из условий действительно занимает время. Также помните, что у вас могут возникать проблемы с параметрами нюхания и, возможно, лучше сделать несколько меньших/специализированных вызовов процедур вместо одного запроса на размер-размер всего –

ответ

0

вы сказали:

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

поэтому я предпочитаю, чтобы попытаться с нарушением условий, в которых (5-е-5-е) с использованием вложенных выборок, также используйте имя столбцов вместо *, поскольку оно не обращает внимания на индексы:

select Field1, Field2, ..., Field20 from 
(select Field1, Field2, ..., Field20 from 
    (select Field1, Field2, ..., Field20 
    from MyTable 
    where Field1 = Value1 and Field2 = Value2 and... Field5 = Value5) 
    where Field6 = Value6 and Field7 = Value7 and... Field10 = Value10) 
where Field11 = Value11 and Field12 = Value12 and... Field15 = Value15 
+0

Спасибо, что поделились этим предложением! Фактически, это был один из моих первых шагов, когда я столкнулся с проблемой, и, к сожалению, в моем случае это не помогло. Более того, во многих случаях план выполнения был точно таким же, как в исходном «неразделенном» запросе. Кроме того, я попытался сформировать подзапрос как представление, а затем применить дополнительные ограничения к представлению - результат был почти таким же, как в случае разделенного запроса. – user2668470

+0

приветствую вас, для меня иногда разделяю запрос с привлечением наиболее ограничительных ограничений для большинства внутренних запросов, решенных такими проблемами, поэтому я отправил этот ответ, так или иначе, надеюсь, вы скоро это исправите, удачи – jfun

+0

Мне очень жаль для тех, кто голосует без ответов – jfun

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