2013-02-23 2 views
-1

Я использовал Row_Number() для реализации поискового вызова в моей хранимой процедуре. Пейджинг работает нормально. Но проблема в том, что после реализации Row_Number() индексы не работают & Кластерный индекс SCAN происходит, даже если я использую столбец первичного ключа по порядку по разделу. ниже приведен пример запроса:индекс не работает при использовании ROW_NUMBER в sql-сервере

SELECT TOP (@insPageSize) A.RowNum, A.AdID, A.AdTitle, A.AdFor, A.AdCondition, 
A.AdExpPrice, A.CreatedDate, A.ModifiedDate, A.AdUID 
FROM 
(
SELECT ROW_NUMBER() OVER (ORDER BY vaa.AdID DESC) AS RowNum, 
    vaa.AdID, vaa.AdTitle, vaa.CityID, vaa.AdFor, vaa.AdCondition, 
    vaa.AdExpPrice, vaa.CreatedDate, vaa.ModifiedDate, vaa.AdUID 
FROM Catalogue.vwAvailableActiveAds vaa 
WHERE vaa.CategoryID = @intCategoryID AND vaa.CountryCode = @chrCountryCode 
     AND vaa.CreatedDate > DATEADD(dd, -90, GETUTCDATE()) 
     AND vaa.StateID = @inbStateID AND vaa.CityID = @inbCityID 
) A 
WHERE A.RowNum > (@insPageSize * (@insPageNo - 1)) 

если я пытаюсь выполнить только внутренний запрос:

SELECT ROW_NUMBER() OVER (ORDER BY vaa.AdID DESC) AS RowNum, 
    vaa.AdID, vaa.AdTitle, vaa.CityID, vaa.AdFor, vaa.AdCondition, 
    vaa.AdExpPrice, vaa.CreatedDate, vaa.ModifiedDate, vaa.AdUID 
FROM Catalogue.vwAvailableActiveAds vaa 
WHERE vaa.CategoryID = @intCategoryID AND vaa.CountryCode = @chrCountryCode 
     AND vaa.CreatedDate > DATEADD(dd, -90, GETUTCDATE()) 
     AND vaa.StateID = @inbStateID AND vaa.CityID = @inbCityID 

Он не использует какой-либо индекс. AdID является первичным ключом &, существует еще один некластеризованный индекс, который охватывает все предложение where. Но происходит сканирование индексов. Если я удалю Row_Number() из внутреннего запроса &, проверьте его план выполнения, все индексы работают нормально, но снова StateID & CityID отображается как «предикат», когда они находятся в некластеризованном индексе.

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

ответ

0

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

Если вы строите индекс на vwAvailableActiveAds(CategoryId, COuntryCode, StateId, CityId, CreatedDate), то он должен использовать этот индекс для предложения where. Приложение row_number() все равно не будет использовать индекс, но предположительно будет располагаться на гораздо меньшем наборе данных.

Кстати, это предполагает, что представление на самом деле является просто выбором в базовой таблице. Если запрос в представлении более сложный (даже с предложением where, join или group by), то этот конкретный индекс может быть не лучшим подходом.

+0

Привет Гордон, представление содержит данные из 4 таблиц и в этих таблицах используется поиск кластеризованного индекса. В моем запросе предложение where содержит фильтр только для базовой таблицы, а моя некластеризованная последовательность индексов: (categoryID, countrycode, createddate, stateID, cityID) включают (название, объявление, условие, цена, измененная дата). AdUid поступает из второй таблицы, которую я использовал в join, и эта таблица имеет кластеризованный индекс и использует поиск индекса. –

+0

@AnujRathi. , , Вы должны иметь 'createddate' в конце списка полей. Он используется для неравенства в предложении 'where'. –

+0

спасибо за ваш совет. У меня также есть googled на другом сайте, я думаю, что это будет хороший вариант. –

2

Что вы ожидаете, ищут? Здесь вы делаете несколько вещей, которые затрудняют выполнение поиска: (a) возврат RANGE строк; (b) сортировка для получения ROW_NUMBER(), с помощью AdID DESC - возможно, не порядок, определяющий ваш PK; (c) фильтрацию от чего-то другого, кроме ПК, и (d) включая много столбцов на выходе, которые вряд ли будут покрыты любым индексом NC. Многие люди бросают руки в воздух и кричат: «О, черт возьми! Это сканирование! Это ужасно!» Даже в тех случаях, когда на самом деле это самый эффективный способ сделать это.

(Просто потому, что искать не происходит вовсе не означает, что «индексы не работают». - это просто означает, что они, вероятно, будет еще менее эффективным в удовлетворении этого запроса)

+0

Привет, Аарон, Спасибо за ваш ответ. Я создал некластеризованный индекс, который охватывает все столбцы «где» и выбранные столбцы в разделе «include». Если бы я запросил запрос без Row_Number, есть поиск индекса. –

+0

@Anuj, как вы ожидаете определить номер строки для каждой строки таблицы, выполнив только поиск? Подумайте об этом на мгновение. –