Лучшие индексы для использования в операторе ИЛИ в SQL Server - PullRequest
2 голосов
/ 16 июня 2010

У меня есть таблица, в которой есть несколько столбцов, но есть два соответствующих:

Due_Amount MONEY<br /> Bounced_Due_Amount MONEY

У меня есть запрос SQL, подобный следующему

SELECT * FROM table WHERE (Due_Amount > 0 OR Bounced_Due_Amount > 0)

Будет ли лучшим индексом для этой таблицы для SQL Server 2008 индекс, который включает оба столбца в индексе, или я должен поместить отдельный индекс в каждый столбец?

Ответы [ 4 ]

6 голосов
/ 16 июня 2010

Индекс не может использоваться на ИЛИ, как это. попробуйте это:

SELECT * FROM table WHERE Due_Amount > 0
UNION ALL  
SELECT * FROM table Bounced_Due_Amount > 0
--use "UNION" if Due_Amount and Bounced_Due_Amount could both >0 at any one time

имеет индекс для Due_Amount и другой для Bounce_Due_Amount.

Может быть, лучше изменить дизайн вашего стола. Не зная вашей бизнес-логики или таблицы, я собираюсь предположить, что у вас может быть столбец «Bounce» Y / N или 1/0 char / bit и просто столбец «Due_Amount». Добавьте индекс для этого «Due_Amount», и запрос будет просто:

SELECT * FROM table WHERE Due_Amount > 0

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

1 голос
/ 16 июня 2010

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

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

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

0 голосов
/ 16 июня 2010

Технически вы можете иметь индекс для сохраняемого вычисляемого столбца и использовать вычисляемый столбец вместо условия OR в запросе, см. Создание индексов для вычисляемых столбцов :

alter table [table] add Max_Due_Amount as
   case 
    when Due_Amount > Bounced_Due_Amount the Due_Ammount
    else Bounced_Due_Amount
   end
   persisted;
go

create index idxTableMaxDueAmount on table (Max_Due_Amount );
go

SELECT * FROM table WHERE Max_Due_Amount > 0;

Но в целом я бы рекомендовал использовать подход UNION, подобный предложенному KM.

0 голосов
/ 16 июня 2010

Специально для этого запроса лучше всего создать индекс для обоих столбцов в том порядке, в котором они используются в предложении where.В противном случае индекс может не использоваться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...