2010-04-19 2 views
1

У меня есть таблица SQL он имеет более 1000000 строк, и мне нужно выбрать с запросом, как вы можете увидеть ниже:Выбор из большой таблицы SQL 2005

SELECT DISTINCT TOP (200) COUNT(1) AS COUNT, KEYWORD 
    FROM QUERIES WITH(NOLOCK) 
    WHERE KEYWORD LIKE '%Something%' 
    GROUP BY KEYWORD ORDER BY 'COUNT' DESC 

Могли бы вы, пожалуйста, скажите, как я могу оптимизировать его, чтобы ускорить процесс выполнения? Спасибо за полезные ответы.

ответ

0

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

Что схемы следует использовать для эффективно удовлетворить запрос как SELECT DISTINCT TOP (200) COUNT(1) AS COUNT, KEYWORD FROM QUERIES WHERE KEYWORD LIKE '%Something%'GROUP BY KEYWORD ORDER BY 'COUNT' DESC, когда таблица имеет ЗАПРОСЫ над рядами 1M ?

Правильная схема зависит от избирательности KEYWORD. Одним из возможных конструкций будет нормализовать KEYWORD в таблице поиска и имеют узкий, не кластерный индекс поиска ID:

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%' вообще в пользу fullt полнотекстового поиска:

SELECT DISTINCT TOP (200) COUNT(1) AS 
COUNT, KEYWORD FROM QUERIES WHERE 
CONTAINS (Keyword, Something) 
GROUP BY 
KEYWORD ORDER BY 'COUNT' DESC 

Поскольку поиск FT является обратным индексом, он может оказаться оптимальным по сравнению с традиционным ГДЕ. Единственная проблема заключается в том, что вы сможете искать только полные слова, так как FT не позволит вам искать частичные совпадения, как это делает LIKE. Опять же, фактический пробег будет зависеть от профиля данных ключевого слова (то есть его статистики и распределения).

+0

Btw, если и downvote, объяснить, почему –

1

Сначала я рассмотрел план выполнения, чтобы увидеть, как сервер sql пытается получить доступ к вашим данным. Here - это ссылка на только одну из многих статей по анализу плана выполнения.

0

Как заявил Джереми, вам нужно посмотреть план выполнения и статистику клиентов, чтобы узнать, что быстрее. Однако несколько предложений. Во-первых, вам действительно нужен шаблон-префикс в вашем поиске? I.e., LIKE '%Something%' не сможет использовать индекс, тогда как LIKE 'Something%' будет. Во-вторых, вы можете попробовать CTE, чтобы увидеть, будет ли быстрее. Так, что-то вроде:

;With NumberedItems As 
    (
    Select Keyword, Count(*) As [Count] 
     , ROW_NUMBER() OVER (ORDER BY Keyword, Count(*) DESC) As ItemRank 
    From Queries WITH (NOLOCK) 
    Where Keyword LIKE '%Something%' 
    Group By Keyword 
    ) 
Select Keyword, [Count] 
From NumberedItems 
Where ItemRank <= 200 
0

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

Если вы действительно хотите вникать в это, вы также можете прочитать на the query optimizer, который пытается выполнить ваш запрос, используя наиболее оптимальный план. Понимание оптимизатора важно для того, чтобы вы в полной мере использовали индексы и т. Д., Которые у вас есть в базе данных. У Microsoft также есть несколько полезных документов, таких как this об устранении проблем с производительностью.

Для вашего конкретного случая узкое место, скорее всего, содержится в предложении WHERE. LIKE сравнения, как правило, неэффективны, особенно когда они окружены процентными знаками, поскольку запрос, как правило, не может использовать индексы в столбце и т. Д. В зависимости от того, как вы сохранили данные, full-text indexing может быть полезным вариантом, поскольку это может часто превосходят LIKE '%SOMEVALUE%'.

0

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

Кроме того, результаты, которые вы получаете, могут быть неточными, если у вас есть некоторые ключевые слова, которые вложены в другие (например, «корзина» будет соответствовать поиску ключевых слов на «машине», что не то, что вы хотите).

0

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

http://en.wikipedia.org/wiki/Inverted_index

Смежные вопросы