Etwas stimmt hier nicht und ich verstehe nicht was. Es ist erwähnenswert, dort gesucht Wert ist nicht in der Tabelle, für einen bestehenden Wert gibt es kein Problem. Warum benötigt die erste Abfrage jedoch eine gruppierte Schlüsselsuche nach dem Primärschlüssel, die in der Abfrage nicht einmal verwendet wird, während die zweite direkt auf dem Index ausgeführt werden kann. Das Erzwingen der Abfrage zur Verwendung des Index WITH (INDEX (Indexname)) funktioniert zwar, aber warum wählt der Optimierer diese nicht selbst aus?SQL Server wählt den Index nicht, obwohl alles darauf hindeutet
Die Spalte PIECE_NUM befindet sich in keinem anderen Index und ist auch nicht der Primärschlüssel.
SET STATISTICS IO ON
DECLARE @vchEventNum VARCHAR(50)
SET @vchEventNum = '54235DDS28KC1F5SJQMWZ'
SELECT TOP 1
fwt.WEIGHT,
fwt.TEST_RESULT
FROM FIN_WEIGHT_TESTS fwt WITH(NOLOCK)
WHERE fwt.PIECE_NUM LIKE @vchEventNum + '%'
ORDER BY fwt.DTTM_INSERT DESC
SELECT TOP 1
fwt.WEIGHT,
fwt.TEST_RESULT
FROM FIN_WEIGHT_TESTS fwt WITH(NOLOCK)
WHERE fwt.PIECE_NUM LIKE '54235DDS28KC1F5SJQMWZ' + '%'
ORDER BY fwt.DTTM_INSERT DESC
SET STATISTICS IO OFF
Ich lasse beiden Abfragen in einer Batch-Lauf:
IO Statistiken berichten:
Abfrage 1: logische liest 16244910
Abfrage 2: logische liest 5
Table 'FIN_WEIGHT_TESTS'. Scan count 1, logical reads 16244910, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'FIN_WEIGHT_TESTS'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Die Tabelle enthält einen nicht gruppierten Index für PIECE_NUM einschließlich aller drei anderen Spalten der Abfrage.
Hier sind die Abfrageausführungspläne (mit einer wenig Bearbeitung der tatsächlichen Namen entfernen):
ich die convert_implicit bemerkt hat, aber das ist nur aufgrund der Umwandlung des varchar Parameters Spalt Nvarchar. Das Ändern des Parametertyps hat das Verhalten der Abfrage nicht geändert.
Warum verwendet die Abfrage mit dem Parameter nicht den Index, während der Parameter durch seinen Wert ersetzt wird?
1 - Bitte ** nicht ** zufällig nolock verwenden: https://sqlstudies.com/2015/03/18/why-not-nolock/ – Milney
2 - Lesen Sie auf Parameter Sniffing: https://www.brentozar.com/archive/2013/06/the-elephant-and-the-mouse-or-parameter-sniffing-in-sql-server/ – Milney
@ Milney Danke für den Link, lesen Sie mehr über Nolock, wie es in unserer gesamten Datenbank stark verwendet wird. Hier ist es nicht mein Code, ich wollte nur herausfinden, warum diese Abfrage jeden Tag Milliarden von Lesevorgängen erzeugt. Wird auch über Parameter Sniffing lesen. Hier dachte ich, alle Hinweise gäbe es für den Optimierer zu wissen, was zu tun ist - nur eine bedingte Spalte, nur ein Index, in dem diese Spalte ist. – AndyZ