Widzę dziwne zachowanie w przypadku następującego zapytania T-SQL w programie SQL Server 2012:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
Samo wykonanie tego zapytania daje mi około 1300 wyników w mniej niż dwie sekundy (włączony jest indeks pełnotekstowy Name
)
Jednak po zmianie zapytania na to:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
OFFSET 0 rows
FETCH NEXT 10 ROWS ONLY
Daje mi 10 wyników dłużej niż 20 sekund.
Następujące zapytanie jest jeszcze gorsze:
SELECT Id
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY Name) AS RowNum, Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"') ) AS RowConstrainedResult
WHERE RowNum >= 0 AND RowNum < 11
ORDER BY RowNum
Wykonanie zajmuje ponad 1,5 minuty!
Jakieś pomysły?
SELECT TOP 10 * .... ORDER BY Name
?Odpowiedzi:
Ponieważ po prostu chcesz
TOP 10
uporządkować według nazwy, myślę, że szybsze jest opracowanie indeksuname
w kolejności i sprawdzenie, czy każdy wiersz pasuje doCONTAINS(Name, '"John" AND "Smith"') )
predykatu.Przypuszczalnie potrzeba 10 dodatkowych wierszy, aby znaleźć 10 wymaganych meczów, niż się spodziewa, a ten problem liczności jest złożony z liczbą kluczowych wyszukiwań.
Szybkie hack, aby zatrzymać go przy użyciu tego planu byłoby zmienić
ORDER BY
, abyORDER BY Name + ''
chociaż przy użyciuCONTAINSTABLE
w połączeniu zeFORCE ORDER
powinna również współpracować.źródło
To wygląda jak klasyczne niedorzeczność selektywności. Nie jestem pewien, co można z tym zrobić, ponieważ „sterownik” zapytania jest wyszukiwaniem pełnotekstowym, którego nie można rozszerzyć o statystyki.
Spróbuj przepisać
where contains
predykat nainner join containstable
( CONTAINSTABLE ) i zastosuj wskazówki dotyczące kolejności łączenia, aby wymusić kształt planu.To nie jest idealne rozwiązanie, ponieważ ma problemy z konserwacją, ale nie widzę innego sposobu.
źródło
Udało mi się rozwiązać problem:
Jak powiedziałem w pytaniu, były indeksy dla wszystkich kolumn + statystyki dla każdej kolumny. (Z powodu starszych zapytań typu LIKE) Usunąłem wszystkie indizes i statystyki, dodałem wyszukiwanie pełnotekstowe i voila, zapytanie stało się naprawdę szybkie.
Wygląda na to, że indeksy doprowadziły do innego planu wykonania.
Dziękuję wszystkim bardzo za pomoc!
źródło