Bei der folgenden T-SQL-Abfrage in SQL Server 2012 tritt ein merkwürdiges Verhalten auf:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
Wenn ich diese Abfrage alleine durchführe, erhalte ich ungefähr 1.300 Ergebnisse in weniger als zwei Sekunden (es gibt einen Volltextindex für Name
).
Wenn ich die Abfrage jedoch in Folgendes ändere:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
OFFSET 0 rows
FETCH NEXT 10 ROWS ONLY
Es dauert mehr als 20 Sekunden, bis ich 10 Ergebnisse erhalte.
Die folgende Abfrage ist noch schlimmer:
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
Es dauert mehr als 1,5 Minuten!
Irgendwelche Ideen?
SELECT TOP 10 * .... ORDER BY Name
?Antworten:
Da Sie nur den
TOP 10
geordneten Namen wünschen , wird es Ihrer Meinung nach schneller sein, den Indexname
in der richtigen Reihenfolge zu bearbeiten und zu prüfen, ob jede Zeile mit demCONTAINS(Name, '"John" AND "Smith"') )
Prädikat übereinstimmt .Vermutlich werden viel mehr Zeilen benötigt, um die 10 erforderlichen Übereinstimmungen zu finden, als erwartet, und dieses Kardinalitätsproblem wird durch die Anzahl der Schlüsselsuchvorgänge verschärft.
Ein schneller Hack, um die Verwendung dieses Plans zu beenden, wäre, das zu ändern
ORDER BY
,ORDER BY Name + ''
obwohl die VerwendungCONTAINSTABLE
in Verbindung mitFORCE ORDER
ebenfalls funktionieren sollte.quelle
Dies sieht nach einer klassischen Fehlschätzung der Selektivität aus. Ich bin mir nicht sicher, was ich dagegen tun kann, wenn der "Treiber" der Abfrage die Volltextsuche ist, die Sie nicht mit Statistiken ergänzen können.
Versuchen Sie, das
where contains
Prädikat in eininner join containstable
( CONTAINSTABLE ) umzuschreiben, und wenden Sie Verknüpfungsreihenfolgenhinweise an, um die Form des Plans zu erzwingen.Das ist keine perfekte Lösung, da es Wartungsprobleme gibt, aber ich sehe keinen anderen Weg.
quelle
Ich habe das Problem gelöst:
Wie ich in der Frage sagte, gab es in allen Spalten Indizes + Statistiken für jede Spalte. (Wegen veralteter LIKE-Abfragen) Ich habe alle Indizes und Statistiken entfernt, die Volltextsuche hinzugefügt und voilà, die Abfrage wurde sehr schnell.
Es scheint, dass die Indizes zu einem anderen Ausführungsplan geführt haben.
Vielen Dank für Ihre Hilfe!
quelle