2012-02-13 2 views
0

У меня есть стол, похожий на 10 000 строк.sql server query performance, где статья

declare @a table 
(
    id bigint not null, 
    nm varchar(100) not null, 
    filter bigint 
    primary key (id) 
) 

Выбор с 4-5 соединением занимает х секунд. Если предложение where добавлено, теперь он занимает 3 раза. Предложение где:

filter = @filder or 
filter is null 

Я применил некластеризованный индекс на колонке, но я получаю только 10% от Perfomance.

Любые советы?

Редактирование: проблема с производительностью возникает при добавлении столбца фильтра. все соединения находятся на первичных ключах.

+2

Используются ли столбцы для объединения какой-либо из индексов? – JeffO

+1

Какие поля вы выбираете?Если у вас 4-5 соединений, эти ключи индексируются на BOTH SIDES соединения? – JNK

+2

Как выглядит ваша производительность, когда вы выполняете 'SELECT filter FROM @a WHERE ........' ?? Если вы выполняете «SELECT *», и, следовательно, индекс, скорее всего, вообще не поможет, поскольку оптимизатор запросов все равно будет проверять всю таблицу (поскольку вы запрашиваете ** все столбцы ** в вашем SELECT). ... –

ответ

1

У меня есть несколько мыслей по этому вопросу:

  1. Скорее всего, что ваш присоединяется присоединяются на table.id - который является первичным ключом и имеет индекс - лото - высокая селективность (поскольку значения являются уникальными) , При индексировании оптимизатор может действительно получить доступ к этой таблице, когда он используется в соединениях.

  2. Я не уверен на 100%, но - либо у вас нет индекса на filter, либо он не является достаточно избирательным. Если у вас нет индекса - оптимизатор будет использовать сканирование таблицы. Если у вас есть индекс, но он не является достаточно избирательным, он будет использовать сканирование таблицы в любом случае. Сканирование дорого.

  3. Даже если у вас есть индекс на filter Оптимизатор не любит OR предикаты. В основном при использовании OR оптимизатор может оказаться в результате сканирования индекса вместо поиска индекса. Попробуйте использовать это вместо: @filder = ISNULL(Filter, @filder как @ sut13.

Так, чтобы улучшить производительность: добавить индекс filter, если вы не один и настроить, где положение, чтобы не использовать OR как я предложил.

также:

Вы не должны ожидать, что запрос с where фильтром для выполнения равной или лучше, чем запрос с 4-5 присоединяется. Если запрос с объединениями более селективен и лучше использует индексы, он будет лучше работать

0

Вероятно, что отсутствие индекса (на основе того, что вы описали в структуре) в столбце фильтра приводит к сканирование таблицы. Единственный способ убедиться в том, чтобы взглянуть на план выполнения запроса. Это скажет вам, что оптимизатор делает с запросом и обычно дает вам достаточно информации, чтобы вы могли понять, почему это делается и что вам нужно сделать, чтобы исправить это.

Возможно, вам нужен указатель на столбце фильтра. Но при условии, что «OR filter IS NULL» может привести к сканированию в любом случае, в зависимости от количества нулевых значений в данных.

Если вы используете ISNULL как указано, к сожалению, это функция в столбце и, вероятно, (в зависимости от используемых индексов и других столбцов в предложении WHERE, который может быть использован для первоначального фильтрации данных и т. Д.). в сканировании, а не в поиске.