2011-06-30 15 views
10

Mamy problem z nadzieją, że dobrzy ludzie w Stack Overflow mogą nam pomóc. Używamy SQL Server 2008 R2 i mamy problemy z zapytaniem, które trwa bardzo długo, aby uruchomić na umiarkowanym zbiorze danych, około 100 000 wierszy. Używamy ZAWIERA do przeszukiwania plików xml i LIKE w innej kolumnie do obsługi wiodących symboli wieloznacznych.Powolne zapytanie SQL z CONTAINS i OR

Mamy powielana problem z następującym małej zapytania, które trwa około 35 sekund, aby uruchomić: planu

SELECT something FROM table1 
WHERE (CONTAINS(TextColumn, '"WhatEver"') OR 
     DescriptionColumn LIKE '%WhatEver%') 

zapytanie:

Slow query

Jeśli zmodyfikować kwerendę powyżej używając Zamiast tego UNION, czas działania spada z 35 sekund do < 1 sekundy. Chcielibyśmy uniknąć stosowania tego podejścia do rozwiązania problemu.

SELECT something FROM table1 WHERE (CONTAINS(TextColumn, '"WhatEver"') 
UNION 
(SELECT something FROM table1 WHERE (DescriptionColumn LIKE '%WhatEver%')) 

Plan Zapytanie:

Fast query

Kolumna że używamy ZAWIERA przeszukiwać jest kolumna z typ obrazu i składa się z plików xml wielkości wszędzie od 1k do 20k w wielkości.

Nie mamy dobrych teorii, dlaczego pierwsze zapytanie jest tak powolne, więc mieliśmy nadzieję, że ktoś tutaj będzie miał coś mądrego do powiedzenia w tej sprawie. Plany zapytania nie pokazują niczego niezwykłego, o ile możemy to stwierdzić. Przebudowaliśmy również indeksy i statystyki.

Czy jest coś oczywistego, że tu jesteśmy?

Z góry dziękujemy za poświęcony czas!

+0

Czy próbowałeś zmienić kolejność klauzul where? – idstam

+0

Tak, już wypróbowaliśmy to. Nie było żadnych mierzalnych różnic w wydajności. – Tilfeldig

+0

Czy możesz uruchomić osobno te dwa zapytania? Który jest wolniejszy? – niktrs

Odpowiedz

4

Dlaczego używasz DescriptionColumn LIKE '%WhatEver%' zamiast CONTAINS(DescriptionColumn, '"WhatEver"')?

CONTAINS to oczywiście predykat pełnotekstowy i będzie używał mechanizmu SQL Server Full-Text do filtrowania wyników wyszukiwania, jednak LIKE jest "normalnym" słowem kluczowym SQL Server, a zatem SQL Server nie będzie używał silnika Full-Text do spełnienia tego zapytania - w tym przypadku, ponieważ termin LIKE rozpoczyna się od wieloznacznego SQL Server nie będzie mógł użyć żadnych indeksów, aby pomóc w zapytaniu, co najprawdopodobniej spowoduje skanowanie tabeli i/lub gorszą wydajność niż użycie opcji Pełna. -Tekstowy silnik.

Jego trudny da się powiedzieć bez planu wykonania, jednak moje przypuszczenie na co dzieje byłoby:

  • UNION odmianą zapytania wykonuje skanowanie tabeli przeciwko table1 - skanowanie tabela nie jest to szybkie, jednak ze względu na to, że w tabeli znajduje się stosunkowo mało wierszy, to nie jest ono zbyt wolne (w porównaniu do benchmarku z lat 35.).

  • W odmianie SQL Server Query OR najpierw stosując silnik pełnotekstowego filtrowanie oparte na CONTAINS a następnie przechodzi do wykonywania odnośnika RDI w każdym rzędzie pasującym do rezultatu, który ma filtrować oparty na LIKE predykat, jednak z jakiegoś powodu SQL Server znacznie zaniża liczbę wierszy (może się to zdarzyć z niektórymi rodzajami predykatów) i tak dalej wykonuje kilka tysięcy wyszukiwań RDI, co kończy się niesamowicie wolną (skanowanie tabeli byłoby o wiele szybsze).

Aby naprawdę zrozumieć, co się dzieje, należy uzyskać plan zapytania.

+0

Powodem, dla którego używamy LIKE do przeszukania "DescriptionColumn", jest umożliwienie wyszukiwania znaków wieloznacznych. Przepraszam, że nie wspomniałem o tym w pierwotnym pytaniu. Plany zapytania zostały dodane do oryginalnego wpisu. – Tilfeldig

1

Czy wy spróbuj tego:

SELECT * 
FROM table 
WHERE CONTAINS((column1, column2, column3), '"*keyword*"') 

Zamiast tego:

SELECT * 
FROM table 
WHERE CONTAINS(column1, '"*keyword*"') 
OR CONTAINS(column2, '"*keyword*"') 
OR CONTAINS(column3y, '"*keyword*"') 

Pierwszym z nich jest o wiele szybciej.

Powiązane problemy