sql >> Databáze >  >> RDS >> Sqlserver

Dynamicky vytvořené SQL vs parametry v SQL Server

Přeskočím argument SQL Injection, který je příliš známý, a zaměřím se pouze na SQL aspekt parametrů vs. bez parametrů.

Když odešlete dávku SQL na server, jakoukoli dávku, musí být analyzována, aby byla pochopena. Jako každý jiný kompilátor musí kompilátor SQL vytvořit AST z textu a poté operujte se syntaktickým stromem. Nakonec optimalizátor transformuje strom syntaxe na prováděcí strom a nakonec vytvoří plán provádění a ten se skutečně spustí. V době temna kolem roku 1995 byl rozdíl, jestli byla dávka dotazem Ad-Hoc nebo uloženou procedurou, ale dnes to nedělá absolutně žádný, všechny jsou stejné.

Parametry nyní dělají rozdíl v tom, že klient, který odešle dotaz jako select * from table where primary_key = @pk odešle přesně stejný text SQL pokaždé, bez ohledu na to, o jakou hodnotu se zajímá. Co se pak stane, je, že celý proces, který jsem popsal výše, je zkratovaný. SQL vyhledá v paměti plán provádění pro nezpracovaný, neanalyzovaný text obdržel (na základě hash digestu vstupu) a pokud je nalezen, provede tento plán. To znamená, že žádná analýza, žádná optimalizace, nic, dávka jde přímo do provedení . Na systémech OLTP, které spouštějí stovky a tisíce malých požadavků každou sekundu, tato rychlá cesta znamená obrovský rozdíl ve výkonu.

Pokud odešlete dotaz ve tvaru select * from table where primary_key = 1 pak ho SQL bude muset alespoň analyzovat, aby pochopil, co je uvnitř textu, protože text je pravděpodobně nový, odlišný od jakékoli předchozí dávky, kterou viděl (dokonce i jediný znak jako 1 vs. 2 dělá celou dávku jinou). Poté bude pracovat s výsledným stromem syntaxe a pokusí se o proces nazvaný Simple Parameterisation . Pokud lze dotaz automaticky paremetrizovat, pak SQL pro něj pravděpodobně najde plán provádění v mezipaměti z jiných dotazů, které byly dříve spuštěny s jinými hodnotami pk, a znovu použije tento plán, takže alespoň váš dotaz nemusí být optimalizován a přeskočíte krok generování skutečného prováděcího plánu. Ale v žádném případě jste nedosáhli úplného zkratu, nejkratší možné cesty, jakého dosáhnete se skutečným klientským parametrizovaným dotazem.

Můžete se podívat do SQL Server, SQL Statistics Object čítač výkonu vašeho serveru. Čítač Auto-Param Attempts/sec zobrazí mnohokrát za sekundu SQL musí přeložit dotaz přijatý bez parametrů na automaticky parametrizovaný. Každému pokusu se lze vyhnout, pokud správně parametrizujete dotaz v klientovi. Pokud máte také vysoký počet Failed Auto-Params/sec je ještě horší, to znamená, že dotazy procházejí celým cyklem optimalizace a generování plánu provádění.



  1. Jak porovnat řetězec verze (x.y.z) v MySQL?

  2. ERROR 1044 (42000):Přístup odepřen pro „root“ se všemi oprávněními

  3. Grib2 to PostGIS rastr - někdo to funguje?

  4. Chyba PostgreSQL 9.0:sloupec t.tgisconstraint neexistuje