У меня есть эта таблица:Индексация снизить стоимость СНП
TopScores
Username char(255)
Score int
DateAdded datetime2
, который будет иметь много строк.
Я выполнить следующий запрос (код хранимой процедуры) против него, чтобы получить лучшие 5 высоких показателей и оценку для конкретного Имени пользователя, которому предшествует человек непосредственно над ними в положении, и человек ниже:
WITH Rankings
AS (SELECT Row_Number() OVER (ORDER BY Score DESC, DateAdded DESC) AS Pos,
--if score same, latest date higher
Username,
Score
FROM TopScores)
SELECT TOP 5 Pos,
Username,
Score
FROM Rankings
UNION ALL
SELECT Pos,
Username,
Score
FROM Rankings
WHERE Pos BETWEEN (SELECT Pos
FROM Rankings
WHERE Username = @User) - 1 AND (SELECT Pos
FROM Rankings
WHERE Username = @User) + 1
Мне пришлось индексировать таблицу, поэтому я добавил кластеризацию: сначала ci_TopScores (имя пользователя) и некластеризованное: nci_TopScores (Dateadded, Score).
В плане запроса было показано, что кластеризация была полностью проигнорирована (до того, как я создал некластеризованное тестирование и был использован в запросе), а логические чтения были больше (по сравнению со сканированием таблицы без какого-либо индекса).
Сортировка была самой дорогостоящей операцией. Таким образом, я скорректировал индексы для кластеризации: ci_TopScores (Score desc, Dateadded desc) и некластеризованный: nci_TopScores (Username).
Все еще стоит того же. Nonclustered: nci_TopScores (Имя пользователя) полностью игнорируется.
Как я могу избежать высокой стоимости сортировки и индексации этой таблицы эффективно?
Замечание: использование 'char (255)' очень неэффективно - оно будет ** всегда ** использовать 255 байт - независимо от того, сколько символов вы храните, даже 'NULL' использует 255 символов! Любая строка длиной более 3-5 символов должна храниться как 'Varchar (n)' –
Спасибо. Я сообщу людям таблицы. – Knightwisp