Frage

Ich habe ein seltsames Problem mit SQL Server 2000 und kann mir einfach keinen Grund dafür vorstellen.

Es gibt zwei Tabellen, beide haben einen kombinierten Primärschlüssel mit einem Cluster -Index. Beide Schlüssel haben die gleiche Struktur:

(VARCHAR(11), INT, DATETIME)   /* can't change this, so don't suggest I should */

Es ist also einfach genug, sich ihnen so anzuschließen:

SELECT t1.Foo, t2.Bar
FROM   table1 t1 INNER JOIN table2 t2 ON t1.VarcharKey = t2.VarcharKey
WHERE  t1.VarcharKey = 'Foo'

Wenn ich mir den Abfrageausführungsplan anschaue, sehe ich Folgendes:

  • Clustered Indexsuch [db]. [DBO]. [Tabelle1]. [PK_Table1] (48%)
  • Clustered Indexsuch [db]. [DBO]. [Tabelle2]. [PK_Table2] (51%)
  • Verschachtelte Schleifen (innere Verbindung) (1%) WARNUNG: Kein Prädikat mit Join
  • Auswählen (0%)

Nun, wenn ich das tue (beachten Sie die Nvarchar -Zeichenfolge!):

SELECT t1.Foo, t2.Bar
FROM   table1 t1 INNER JOIN table2 t2 ON t1.VarcharKey = t2.VarcharKey
WHERE  t1.VarcharKey = N'Foo'

Ich bekomme:

  • Clustered Index Scan [DB]. [DBO]. [Tabelle1]. [PK_Table1] (98%)
  • Clustered Indexsuch [db]. [DBO]. [Tabelle2]. [PK_Table2] (1%)
  • Verschachtelte Schleifen (innere Verbindung) (1%) Keine Warnung hier
  • Auswählen (0%)

Dieses Verhalten lässt mich ein bisschen verwirrt.

  • Warum gibt es eine Warnung "No Joy Predicate" und warum verschwindet sie, wenn ich mich verändere? 'Foo' zu N'Foo'? Meine Schlüsselspalten sind nicht vom Typ nvarchar, so dass dies keinen Unterschied machen sollte, oder sollte dies?
  • Hat das Vorhandensein dieser Warnung negative Auswirkungen oder kann ich sie ignorieren?
  • Warum wechselt es von einem Index zu einem Index -Scan?

Einige Hintergrundinformationen: Tabelle Cardinality ist ca. 25.000 Aufzeichnungen One Table, ca. 12.000 Aufzeichnungen in den anderen. Die Datenbankkompatibilitätsstufe beträgt 80 (SQL Server 2000) Standardkollation SQL_Latin1_General_CP1_CI_AS, wenn das überhaupt einen Unterschied macht.

Hier ist der Inhalt von @@VERSION:

Microsoft SQL Server 2000 - 8.00.2273 (Intel x86) 7. März 2008 22:19:58 Copyright (C) 1988-2003 Microsoft Corporation Enterprise Edition unter Windows NT 5.0 (Build 2195: Service Pack 4)

PS: Ich bin mir bewusst KB322854, aber das ist es natürlich nicht.

War es hilfreich?

Lösung

Warum wechselt es von einem Index zu einem Index -Scan?

Dies ist größtenteils eine Vermutung, aber hier geht:

Im ersten Fall ('foo') erkennt MSSQL an, dass der Wert der Suche perfekt für den ersten Teil des Index auf T1 übereinstimmt, und verwendet daher den Index, um einen Datensatz in T1 zu finden (Indexseuch, möglicherweise eine Binärdatei Suche). Nach einem Datensatz in T1 mit einem Index, der perfekt T2 entspricht, kann der Index in T2 Datensätze finden.

Im zweiten Fall (N'Foo ') erkennt MSSQL, dass es keine perfekte Übereinstimmung zwischen dem Index und dem gesuchten Wert hat, sodass er den Index nicht als Index verwenden kann, sondern einen vollständigen Tabellen -Scan durchführen muss. Da der Index jedoch die benötigten Informationen (in unterschiedlicher Form) enthält und kleiner als die vollständige Tabelle ist, kann er einen vollständigen Scan des Index durchführen, als wäre es die Tabelle (dies ist schneller als das Scannen der Tabelle, da weniger Seiten Ich muss für die Festplatte gelesen werden; Mevertht.

Andere Tipps

Von SQLServercentral:

Die Abfragen können einen perfekt geformten Join -Zustand aussehen. Wenn Sie jedoch den Abfrageplan untersuchen, werden Sie eine Warnung sehen, die angibt, dass "No Join Predicate" angibt, dass 2 der beteiligten Tabellen kein Prädikat haben (wenn sie verbunden sind). Das Hinzufügen einer Option (Kraftreihenfolge) zur Abfrage erzeugt einen völlig anderen Plan und die Warnung verschwindet (in einigen Fällen). So wissen Sie, dass dies das Problem ist. Die meisten Abfragen, die ich gesehen habe, die bei SQL 2000 besser abschneiden, zeigen dieses Problem. Das kumulative Update 4 bis SP 2 soll das Problem lösen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top