2012-04-05 13 views
3

ich die einfache Abfrage auf SQL Server 2008 R2 für die folgende Tabelle ausgeführt wird:SQL Server 2008 R2 hat CONVERT_IMPLICIT Tinyint zu wenig

Id (int, nicht null)
aktiviert (Bit, nicht null)

Beide Spalten haben separate Indizes.

Also, wenn ich die folgende Abfrage:

SELECT Id FROM Entities WHERE Enabled = 1 

Ausführungsplan zeigen, dass ein INDEX_SCAN getan wird (es durch CONVERT_IMPLICIT auf Spalte Aktiviert verursacht wird)

Und wenn ich laufe eine weitere Abfrage:

SELECT Id FROM Entities WHERE Enabled = '1' 

oder

SELECT Id FROM Entities WHERE Enabled = 'true' 

oder

SELECT Id FROM Entities WHERE Enabled = CAST(1 AS BIT) 

Ausführungsplan zeigt, dass INDEX_SEEK erfolgt.

Da CONVERT_IMPLICIT die Leistung in komplexeren Abfragen beeinträchtigen kann, möchte ich wissen, was bewirkt, dass sich SQL Server so verhält?

UPD:

Wenn ich

SELECT Id FROM Entities WHERE Enabled = 0 

laufen und dann

SELECT Id FROM Entities WHERE Enabled = 1 

Ausführungsplan zeigt INDEX_SEEK. In diesem Fall habe ich SQL Server einige Optimierungsstatistiken gesammelt und schließlich gelernt, dass es keinen Grund für eine CONVERT_IMPLICIT gibt. Leider kann ich nicht garantieren, dass meine erste Anfrage jemals mit dem entgegengesetzten Wert ausgeführt wird.

Ich werde mit jeder Klärung, die ich bekommen kann, glücklich sein.

+0

Die Selektivität von Bitfeldern (wie Enabled) ist normalerweise sehr schlecht - möglicherweise ist das der Grund, warum der Optimizer so empfindlich auf die erste zwischengespeicherte Ausführung reagiert? – StuartLC

+0

In meinem Fall passiert es nicht nur bei der ersten Ausführung, es passiert, bis die Abfrage mit dem entgegengesetzten Wert ausgeführt wird. Und das ist ziemlich traurig ... – Aides

Antwort

3

Verwenden Sie eine Datenbank im Kompatibilitätsmodus 2000? Wie ich lese here, wenn Sie diesen Kompatibilitätsmodus verwenden Sie dieses "Problem", aber mit 2005 oder 2008 Kompatibilitätsmodus Sie nicht.

Wenn Sie also den Kompatibilitätsmodus 2000 verwenden müssen, müssen Sie die Vergleiche "= '1'" verwenden, um CONVERT_IMPLICIT zu vermeiden, da der Typ Vorrang hat zwischen Bit und int (oder tiny int) "upgraden" zu int.

+0

Ich markiere deine Antwort akzeptiert, wie es für andere nützlich sein kann. Allerdings habe ich das behoben mit (CAST als Bit) – Aides

+0

vielen Dank –

+1

Sehr interessant, ich stieß auch auf diese Microsoft Connect-Anfrage für ein bisschen literales Format: http://connect.microsoft.com/SQLServer/feedback /details/611171/t-sql-Soll-ein-Bit-Literal-Format –

Verwandte Themen