Categories: SQL ServerT-SQL

Zur falschen Zeit am falschen Ort – Datentypen

Eine ganz banale Vergesslichkeit kann zu ungewollten Performanceeinbußen führen. Aufgefallen ist mir diese – sagen wir mal Unachtsamkeit bei Erstellung von Tabellen im SSMS. Gerne klickt man schnell durch und übersieht, dass der Standard für Datentypen ein nchar(10) ist. Kein Problem, solange das auch gewollt ist. Aber wenn nicht..?

PROBLEM

 

Sehen wir uns mal folgendes Statement an:

select * from bestdemo where Frachtkosten = 10

Das Ergebnis stimmt, aber wenn man sich den Ausfürhgunsplan ansieht, bemerkt man ein kleines Ausrufezeichen im Select. Warum dies. Naja, man hat für die Frachtkosten ein nnachr(10) angegeben. In der Abfrage allerdings verwenden wir einen Vergleich auf die 10, sprich eine Zahl. Oder aus SQL Server Sicht einen int-Wert! Demnach bleibt nichts anderes übrig, als den Wert in der Tabelle implizit konvertieren zu lassen.

Was nun kommt ist weit weniger schön. Durch das implizite Konvertieren, muss er einerseits eine grobe Schätzung vornehmen, wieviele Zeilen zurückkommen und kann eine evtl bestehenden Index nicht mehr verwenden! Performance ade!

Im Plan sieht man sehr deutlich das Ausrufezeichen im SELECT. Hinweis, dass hier etwas nicht stimmt. Weiterhin ist auffällig, dass bei der Abfrage eine CLUSTERED INDEX SCAN verwendet wird, obwohl eine NON Custered die Arbeit hätte gut übernehmen können. (Ok ..Verzeihung, das * sollte natürlich nicht sein, aber selbst bei Angabe der Spalten, würde dennoch ein CLUSTRED INDEX SCAN blieben). Der Hinweis des SELECT im Plan sieht genauer so aus:

 

Hier wird die Typenkonvertierung deutlich!

LÖSUNG

Abgesehen davon, dass man in der Tabelle wohl besser mit einem int statt einer nchar hätte machen sollen, ist die Lösung banal: Verwende in der Abfrage einen String, sprich char.

select * from bestdemo where Frachtkosten = '10'

Die 10 unter Hochkommas verschafft uns folgenden Plan:

Nun ist der Plan in Ordnung und benutzt den deutlichen günstigeren INDEX SEEK.

Übrigens: Das Problem wäre andersrum nicht entstanden, wenn der Datentyp int gewesen wäre und wir die 10 unter Hochkommas gesetzt hätten..

Also aufpassen

Fumus

Share
Published by
Fumus

Recent Posts

SQL Server 2019 – static data masking – Du Opfer!

In SQL Server 2016 wurde das sog. dynamic data masking eingeführt. Eine Möglichkeit Daten bei…

5 Jahren ago

MinRole – Oder wie alles etwas einfacher wird

Seit Sharepoint Server 2007 präsentiert sich die Installation immer auf die gleiche Weise. Gerade mal,…

8 Jahren ago

Schritt für Schritt: SQL 2016 – Dynamic Data Masking

Es weihnachtet! Gerade bekam ich von einer Kollegin Plätzchen angeboten mit der Größe eines Diskus…

8 Jahren ago

Schritt für Schritt: SQL Server 2016 – temporal tables

Nein, bitte nicht verwechseln: temporal tables haben nichts zu tun mit temporary tables table variables…

9 Jahren ago

SQL Server 2016 Schritt für Schritt–Installation und First Look

SQL Server 2016.. habe ich schon erwähnt, dass ich den ziemlich cool finde? Wollen wir…

9 Jahren ago

SQL Server 2016 – CTP2

Nach langer Zeit wieder mal eine Artikel von mir.. der mich besonders erfreut. SQL Server…

9 Jahren ago