Задать вопрос о производительности SQL Server без предоставления схемы - пустая трата времени каждого. Я собираюсь ответить на другой вопрос, который вы должны были задать в первую очередь:
Какую схему мне использовать для
эффективно удовлетворить запрос как
SELECT DISTINCT TOP (200) COUNT(1) AS
COUNT, KEYWORD FROM QUERIES WHERE
KEYWORD LIKE '%Something%'GROUP BY
KEYWORD ORDER BY 'COUNT' DESC
когда таблица QUERIES имеет более 1М строк?
Правильная схема зависит от селективности KEYWORD
. Один из возможных вариантов - нормализовать KEYWORD в таблице поиска и иметь узкий некластеризованный индекс для идентификатора поиска:
CREATE TABLE KEYWORDS (KeywordId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
Keyword VARCHAR(...) UNIQUE);
CREATE TABLE QUERIES (...,
KeywordId INT NOT NULL,
CONSTRAINT FK_KEYWORD
FOREIGN KEY KeywordId
REFERENCES KEYWORDS (KeywordId),
...);
CREATE INDEX ndxQueriesKeyword ON Queries (KeywordId);
Если количество отдельных ключевых слов относительно мало, исходный запрос может быть быстро удовлетворен сканированием таблицы Keywqord, за которым следует сканирование диапазона непрямых циклов индекса ndxQueriesKeyword, которое очень узкое и поэтому генерирует низкий IO.
По мере увеличения числа отдельных ключевых слов в этом подходе могут начаться проблемы из-за большого числа сканирований диапазона в таблице запросов и, возможно, даже из-за полного сканирования таблицы ключевых слов.
Вы можете рассмотреть возможность использования другого предложения WHERE, а именно одного LIKE 'Something%
, которое является SARGable и может использовать индекс для KEYWORK, получая выгоду от сокращения диапазона и более узкого сканирования, чем полное сканирование таблицы.
Если вы используете Enterprise Edition, вы можете рассмотреть возможность добавления представления индексов с предварительно вычисленными агрегатами:
CREATE VIEW vwQueryKeywords
WITH SCHEMABINDING
AS SELECT KEYWORD, COUNT_BIG(*) as COUNT
FROM dbo.QUERIES
GROUP BY KEYWORD;
CREATE CLUSTERED INDEX cdxQueryKeywords ON vwQueryKeywords(KEYWORD);
На EE оптимизатор будет рассматривать индексированное представление для исходного запроса. На не-EE вам придется изменить запрос для выполнения с представлением с подсказкой NOEXPAND:
SELECT KEYWORD, COUNT
FROM vwQueryKeywords WITH(NOEXPAND)
WHERE KEYWORD LIKE '%Something%';
Еще один совершенно другой подход - полностью отказаться от условия LIKE '%Something%'
в пользу полнотекстового поиска:
SELECT DISTINCT TOP (200) COUNT(1) AS
COUNT, KEYWORD FROM QUERIES WHERE
CONTAINS (Keyword, Something)
GROUP BY
KEYWORD ORDER BY 'COUNT' DESC
Поскольку поиск FT является поиском обратного индекса, он может оказаться оптимальным по сравнению с традиционным WHERE. Единственная проблема заключается в том, что вы сможете искать только полные слова, так как FT не позволит вам искать частичные совпадения, как это делает LIKE. Опять же, фактический пробег будет варьироваться в зависимости от профиля данных ключевого слова (т.е. его статистики и распределения).