Categories: SQL ServerT-SQL

Verschätzt – AdHoc Abfragen Probleme

Ich kenne nicht viele Systeme, deren SQL Logik nicht in Prozeduren verpackt worden wäre, aber dennoch.. es gibt sie. Sofern sie ebenfalls vorhaben, mehrfach AdHoc Abfragen an den Server zu stellen, in dem Sie beispielsweise auf Prozeduren in Anwendungen verzichten, dann sollten sie sich folgenden Umsatnd überlegen.

Autoparametrisierung

SQL Server versucht Abfragen zu parametrisieren, um Ausführungspläne wiederverwenden zu können. Gründe dafür sind natürlich Performance. Ein Plan muss erst erstellt werden, in dem Statistiken zu Rate gezogen werden und Entscheidungen über die Wahl von Indizes getroffen werden. Eine Autoparametrisierung erkennen Sie beispielsweise sehr leicht im tatsächlichen Ausführungsplan:


Leider hält sich diese Möglichkeit in Grenzen. Verwenden Sie beispielsweise einen Join, so verliert der SQL Server diese Fähigkeit.


Das bedeutet die Pläne werde so wie sind im Speicher abgelegt:


Nehmen wir mal an, wir würden bei dieser Abfrage 100 verschiedene Werte abfragen wollen, so ergeben sich im Arbeitsspeicher 100 Pläne!

Selbst bei einfachen Fragen kann man auf Probleme stoßen:

Führen sie mal folgende Abfrage einzeln aus:


So ergeben sich folgende Pläne im Speicher:

SQL Server schätzt bei Übergaben eines Parameters den nächst günstigen Datentyp ein. Im Falle von orderid=50 auf einen tinyint. Blöderweise passt der allerdings nicht mehr für orderid=500, Dazu muss also schon ein smallint her. Doch auch der paßt nicht mehr für die 50000. Somit müssen 3 Plne angelegt werden.

Die Lösung für die obigen Probleme können durchaus Prozeduren sein, da hier von Anfang an mit vordefinierten Datentypen parametrisiert wird. Die Allroundlösung für dynamisches SQL sind Prozeduren allerdings auch nicht unbedingt, aber das steht auf einen Blatt.

Tests

Wer hier diese Beispiele nachvollziehen möchte, der sollte vorher mal den Prozedurencache löschen, sonst kann das eine gute Weile dauern, bis man den kompletten Cache ausgelesen hat  

Verwenden Sie dazu, wenn möglich nicht dbb freeproccache sondern dbcc flushprocindb(7) wobei die 7 für die Datenbank ID steht. Damit verwerfen sie den eigtl. wertvollen Cache nur für die jeweilige Datenbank.

Um die Pläne zu sehen können Sie folgende Abfrage verwenden:

select usecounts, cacheobjtype,[TEXT] from
    sys.dm_exec_cached_plans P
        CROSS APPLY sys.dm_exec_sql_text(plan_handle)
    where cacheobjtype ='Compiled PLan'
        AND [TEXT] not like '%dm_exec_cached_plans%'
        AND [TEXT]Not like '%filetable%'

 

 

Also passen sie gut auf.. !

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