Оптимизация полнотекстового поиска по нескольким таблицам - PullRequest
5 голосов
/ 20 января 2012

У меня есть требование искать несколько разных таблиц в моей базе данных SQL Server. И мне нужно отсортировать результаты, основываясь на том, в какой таблице произошло совпадение.

Подход, который я выбрал, показан ниже. Тем не менее, это не очень эффективно, так как объем данных растет.

Может кто-нибудь предложить какие-нибудь хитрости, чтобы оптимизировать это?

-- Full-text query
DECLARE @FtsQuery nvarchar(100)
SET @FtsQuery = 'FORMSOF(INFLECTIONAL, detail)'

-- Maximum characters in description column
DECLARE @MaxDescription int
SET @MaxDescription = 250

SELECT 1 AS RankGroup, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) AS Description FROM Table1
    INNER JOIN CONTAINSTABLE(Table1, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table1.Id
UNION SELECT 2, FTS.Rank, Id, Title, NULL FROM Table2
    INNER JOIN CONTAINSTABLE(Table2, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table2.Id
UNION SELECT 3, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) FROM Table3
    INNER JOIN CONTAINSTABLE(Table3, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table3.Id
UNION SELECT 4, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) FROM Table4
    INNER JOIN CONTAINSTABLE(Table4, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table4.Id
UNION SELECT 5, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) FROM Table5
    INNER JOIN CONTAINSTABLE(Table5, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table5.Id
ORDER BY RankGroup, Rank DESC

Одна идея, которую я рассмотрел, - это создать индексированное представление и затем выполнить поиск по представлению. Но поскольку представлению потребуются эти UNION s, трудно понять, насколько это будет более эффективным.

1 Ответ

7 голосов
/ 20 января 2012

Это сложная проблема, потому что CONTAINSTABLE может выполнять поиск только по индексу FTS одной таблицы за раз.Ваше решение UNION, указанное выше, подойдет, если ваша производительность приемлема.

Мы столкнулись с той же проблемой необходимости эффективного поиска множества столбцов из многих таблиц в одном запросе.Мы собрали все данные из этих столбцов и таблиц в единую таблицу только для чтения.Тогда нашему запросу потребовался только один вызов CONTAINSTABLE

 CONTAINSTABLE(AggregatedTable, AggregatedColumn, @FtsQuery)

У нас есть запланированное задание, которое выполняется каждые 5-10 минут и постепенно объединяет любой измененный контент из нашей исходной таблицы в нашу единственную таблицу только для чтения.

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

...