Сканирование таблицы и индексы - PullRequest
2 голосов
/ 02 мая 2011

Я проверил выполнение медленно выполняющегося запроса, который часто выполняю. Это показывает сканирование таблицы большой таблицы.

Вот запрос:

declare @DateAdded datetime

set @DateAdded = '5/1/2011'

SELECT     tblHero.fldHeroName,players.Alliance, 
    tblHero.fldHeroOwner, players.ActIndex, players.fldPlayerCities, 
    tblHero.fldHeroLevel, tblHero.fldHeroPower, 
    players.fldPlayerPrestige, players.fldPlayerName 
FROM         tblHero INNER JOIN 
(
    SELECT     MAX(fldPlayerCities) AS fldPlayerCities, MAX(fldPlayerAlliance) AS     Alliance, 
            MAX(fldPlayerPrestige) AS fldPlayerPrestige, fldPlayerName, 
            MAX(fldPlayerPrestige) - AVG(fldPlayerPrestige) AS ActIndex 
    FROM tblPlayer WHERE (fldPlayerDateAdded >= DATEADD(dd, - 4, @DateAdded)) GROUP BY     fldPlayerName
 ) players 
 ON tblHero.fldHeroOwner = players.fldPlayerName 
 WHERE     (tblHero.fldHeroIsHistoric = 1 or fldHeroLevel = 100) and 
    fldHeroDateAdded = @DateAdded 
 ORDER BY players.ActIndex, players.fldPlayerCities, players.fldPlayerPrestige

Предикат от сканирования таблицы:

[dbo]. [TblHero]. [FldHeroDateAdded] = [@ DateAdded] И ([dbo]. [TblHero]. [FldHeroIsHistoric] = (1) ИЛИ [dbo]. [TblHero]. [FldHeroLevel] = ( 100))

В таблице указаны следующие индексы:

CREATE NONCLUSTERED INDEX IX_tblHero_2 ON dbo.tblHero
    (
    fldHeroDateAdded DESC,
     fldHeroIsHistoric DESC
    ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,       ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 GO
 CREATE NONCLUSTERED INDEX IX_tblHero_3 ON dbo.tblHero
    (
    fldHeroDateAdded DESC,
    fldHeroLevel DESC
    ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,       ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 GO

И, наконец, вопрос:

Какие индексы я должен добавить, чтобы избавиться от сканирования таблицы и ускорить это?

Ответы [ 3 ]

2 голосов
/ 02 мая 2011

Вам нужен индекс для fldPlayerDateAdded для tblPlayer, так как он выполняет поиск по диапазону дат.Вы также можете попробовать добавить отдельный индекс для fldPlayerName.Составные индексы будут выполнять ту же функцию, но упорядочивать их вместе, что может быть приемлемо для этой ситуации, но не является подходящей ситуацией для всех различных ситуаций, которые вы можете иметь или не иметь.Запросы диапазона дат также лучше подходят для кластерных индексов (диапазонов в целом), но у вас, вероятно, есть кластерный индекс уже на ПК.

0 голосов
/ 13 апреля 2013

Вы можете использовать подсказку OPTION (RECOMPILE) в конце сценария Sql, эту подсказку заставляют перекомпилировать план запроса, эта опция полезна, когда инструкция Sql используется с параметрами дифференциала, переданными в de sp, просто выполните тест.

0 голосов
/ 02 мая 2011

Здесь есть несколько возможностей ...

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


В противном случае может показаться, что это связано с объединением подзапроса. Если это так, SQL Server определяет, что (fldPlayerDateAdded >= DATEADD(dd, - 4, @DateAdded)) является наиболее важным предикатом. Поэтому он сначала генерирует результаты подзапроса, а затем присоединяется к таблице tblHero. Это дает как минимум два варианта ...

РЕДАКТИРОВАТЬ - Это может быть отчасти связано с тем, что все предложения ORDER BY взяты из подзапроса. Возможно, попробуйте без ORDER BY, чтобы увидеть, имеет ли это какое-либо отношение.

Во-первых, если нет, вы можете добавить индекс для (fldPlayerDateAdded, fldPlayerName) в tblPlayer. Это, возможно, позволит оптимизатору сначала отфильтровать таблицу tblHero, а затем присоединиться к подзапросу.

В качестве альтернативы, чтобы сохранить тот же базовый план выполнения, но ускорить его, включите поле fldHeroOwner в свои индексы на tblHero.


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

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