2012-01-19 13 views
5

Mam wymóg wyszukiwania kilku różnych tabel w mojej bazie danych SQL Server. I muszę posortować wyniki na podstawie, w której tabeli wystąpił mecz.Optymalizacja wyszukiwania pełnotekstowego w wielu tabelach

Podejście, które podjąłem, przedstawiono poniżej. Jednak nie wydaje się to bardzo skuteczne, ponieważ ilość danych rośnie.

Czy ktoś może sugerować jakieś sztuczki, aby to zoptymalizować?

-- 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 

Jedną z rozważanych przeze mnie idei jest utworzenie widoku indeksowanego, a następnie wykonanie wyszukiwania w widoku. Ale ponieważ widok wymagałby tych UNION s, trudno jest zobaczyć, jak byłoby to bardziej wydajne.

+0

Jedną z prostych optymalizacji, którą można bezpiecznie wykonać, jest zastąpienie "UNION" słowem "UNION ALL". Aby uzyskać więcej informacji: http://stackoverflow.com/questions/49925/what-is-the-difference-between-union-and-union-all – niaher

Odpowiedz

7

Jest to trudny problem, ponieważ CONTAINSTABLE może wyszukiwać tylko indeks FTS jednej tabeli naraz. Twoje rozwiązanie UNION powyżej jest w porządku, o ile twoja wydajność jest akceptowalna.

Mieliśmy do czynienia z tym samym problemem konieczności skutecznego wyszukiwania wielu kolumn z wielu tabel w jednym zapytaniu. Zrobiliśmy agregację wszystkich danych z tych kolumn i tabel w jedną tabelę tylko do odczytu. Nasze zapytanie tylko wtedy potrzebny pojedynczy CONTAINSTABLE połączenia

CONTAINSTABLE(AggregatedTable, AggregatedColumn, @FtsQuery) 

Mamy zaplanowaną pracę, która kursuje co 5-10 minut i stopniowo agreguje żadnej zmodyfikowaną treść naszej tabeli źródłowej do naszego pojedynczego odczytu tylko zagregowanej tabeli zawartości.

Generalnie wydaje się, że używanie FTS w dowolnej bazie danych o rozsądnej wielkości i obciążenie użytkownika oznacza, że ​​zawsze walczysz z wydajnością. Jeśli okaże się, że bez względu na to, co robisz, nie można uzyskać wydajności do zaakceptowania, być może trzeba będzie zbadać inne technologie, takie jak Lucene.

+0

Interesujące. Jakiego rodzaju podejście podjąłeś, aby pobrać zmienione dane i przenieść je do tabeli zbiorczej? I jak długo zajmuje to zwykle zaplanowane zadanie? – mg1075

+1

Używamy zapisanego procesu, który jest zaplanowany przez agent sql, aby zaktualizować zdenormalizowaną tabelę. Nasze dane podstawowe mają datak-stempel w każdym rzędzie wskazujący, kiedy ostatni raz został on dotknięty (wstawiony lub zaktualizowany), więc używamy tego po prostu do tworzenia przyrostowej populacji co 5 lub 10 minut. Nasze początkowe obciążenie zajęło około godziny, ale przyrostowe populacje trwają tylko 10 lub 20 sekund. –

+0

Dzięki za wejście. Przypuszczam, że jedynymi problemami są: (1) czas potrzebny na wysłanie zapytania do tabel w celu ustalenia rekordów kwalifikujących się do aktualizacji oraz (2) jeśli wystąpił jakiś przestój i aktualizacja, która normalnie by działała - i wyglądała na rekordach tylko do tej pory w czasie - nie udało się uruchomić. – mg1075

Powiązane problemy