Sql Server выполняет полное сканирование таблицы, когда первое поле в PK имеет несколько различных значений - PullRequest
1 голос
/ 24 марта 2012

У меня есть эта таблица (Таблица A):

(
    [FieldA] [int] NOT NULL,
    [FieldB] [int] NOT NULL,
    [Value] [float] NULL
CONSTRAINT [PK_TableA] PRIMARY KEY CLUSTERED 
(
    [FieldA] ASC,
    [FieldB] ASC
)

Существует несколько различных значений FieldA, скажем, FieldA может быть {1,2,3,4,5,6}.

Почему этот запрос вызывает полное сканирование таблицы:

SELECT COUNT(*) FROM TableA WHERE FieldB = 1

Хотя это не так:

SELECT COUNT(*) FROM TableA WHERE FieldB = 1 where FieldA in (1,2,3,4,5,6)

Не может ли сервер Sql оптимизировать это?Если бы у меня был TableB, где FieldA был PK, и я присоединился к TableB и TableA, запрос выполнялся бы аналогично второму запросу.

Ответы [ 2 ]

1 голос
/ 11 апреля 2012

Очевидно, что я искал оптимизацию с пропуском сканирования, которая доступна в Oracle, но не в SQL Server. Пропуск сканирования может использовать индекс, если отсутствует предикат переднего края столбца: http://social.msdn.microsoft.com/Forums/eu/transactsql/thread/48de15ad-f8e9-4930-9f40-ca74946bc401

1 голос
/ 24 марта 2012

Кластерный индекс, который вы создали, основан на двух столбцах.Если вы выполняете поиск только по одному из этих столбцов, SQL Server не может сгенерировать «ключевое» значение для использования в процессе поиска по этому индексу, поэтому он возвращается к подходу сканирования таблицы.

Несмотря на то, что FieldA имеет очень маленький диапазон значений, которые он может содержать, оптимизатор SQL не смотрит на этот диапазон значений, чтобы определить, может ли он «выдумать» ключ из предоставленной вами информации.

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

...