Как заменить сканирование кластеризованного индекса поиском некластеризованного индекса или поиском кластерного индекса? - PullRequest
1 голос
/ 21 июля 2011

Ниже приведен скрипт создания таблицы: -

CREATE TABLE [dbo].[PatientCharts](
[PatientChartId] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
[FacilityId] [uniqueidentifier] NOT NULL,
[VisitNumber] [varchar](200) NOT NULL,
[MRNNumber] [varchar](100) NULL,
[TimeIn] [time](7) NULL,
[TimeOut] [time](7) NULL,
[DateOfService] [date] NULL,
[DateOut] [date] NULL),

У меня есть один кластеризованный индекс для PatientChartId и два некластеризованных индекса для VisitNumber и MRNNumber. В этой таблице миллионы записей.

Следующий запрос выполняет сканирование кластерного индекса: -

SELECT  *
FROM    dbo.PatientCharts
INNER JOIN ( SELECT FacilityID
                 FROM   Facilities
                 WHERE  RemoteClientDB IN (
                        SELECT  SiteID
                        FROM    RemoteClient WITH ( NOLOCK )
                        WHERE   Code = 'IN-ESXI-EDISC14'
                                )
               ) AS Filter ON dbo.PatientCharts.FacilityId = Filter.FacilityID   

Это сканирование кластерного индекса занимает много времени в производстве из-за объема данных.

План выполнения: -

enter image description here

Я даже пытался добавить некластеризованный индекс на FacilityID и включить PatientChartID, но тот же план выполнения.

Я делаю DBCC FREEPROCCACHE каждый раз, чтобы указывать серверу sql каждый раз использовать новый план.

Есть ли что-нибудь еще, что я должен сделать, чтобы предотвратить кластеризованное сканирование индекса?

Ответы [ 4 ]

2 голосов
/ 22 июля 2011

Будет выполнено кластерное сканирование, так как нет индекса для поддержки вашего запроса. Даже если вы индексируете FacilityID и PatientChartID, вы все равно потенциально запрашиваете достаточное количество данных для сканирования из-за преодоления переломного момента (Google Kimberly Tripp Tipping Point)

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

0 голосов
/ 14 июня 2012

Я думаю, вам следует избегать ввода SELECT * и указать требуемые кулоны. Затем вы можете планировать свои индексы на план выполнения, который вы получаете

0 голосов
/ 19 января 2012

Как упоминал Эндрю, ваш кластеризованный индекс не помогает вам и не причиняет вам вреда - если у вас нет кластеризованного индекса, вы увидите вместо этого сканирование таблицы (что, я уверяю, будет не более забавным, чемсканирование кластеризованного индекса).

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

0 голосов
/ 09 декабря 2011

Вы пытались реализовать это как прямой запрос с внутренними объединениями вместо использования подзапросов для каждого шага?

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

select * from patientschart...
inner join facilities...
inner join remoteclientdb....
where...

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

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

Надеюсь, это поможет.

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