sql >> Databáze >  >> RDS >> Database

Výkonnostní překvapení a předpoklady:SET NOCOUNT ON

Pokud jste někdy používali Management Studio, bude vám tato výstupní zpráva pravděpodobně povědomá:

(1 ovlivněný řádek)

Toto pochází z DONE_IN_PROC SQL Serveru zpráva, která se odešle po úspěšném dokončení jakéhokoli příkazu SQL, který vrátil výsledek (včetně načtení plánu provádění, což je důvod, proč vidíte dvě z těchto zpráv, když jste ve skutečnosti provedli pouze jeden dotaz).

Tyto zprávy můžete potlačit pomocí následujícího příkazu:

SET NOCOUNT ON;

Proč bys to dělal? Protože tyto zprávy jsou chatové a často neužitečné . Ve svých prezentacích Bad Habits and Best Practices často mluvím o přidání SET NOCOUNT ON; ke všem uloženým procedurám a jeho zapnutí v kódu aplikace, který odesílá dotazy ad hoc. (Během ladění však možná budete chtít příznak pro opětovné zapnutí zpráv, protože výstup může být v těchto případech užitečný.)

Vždy jsem přidal prohlášení, že rada zapnout tuto možnost všude není univerzální; záleží. Staré sady záznamů ADO je ve skutečnosti interpretovaly jako sady výsledků, takže jejich přidání do dotazů po faktu by ve skutečnosti mohlo přerušit aplikace, které je již ručně přeskakují. A některé ORM (kašel NHibernate kašel ) skutečně analyzovat výsledky k určení úspěšnosti příkazů DML (fuj!). Prosím otestujte své změny.

Vím, že v jednu chvíli jsem si dokázal, že tyto chatové zprávy mohou ovlivnit výkon, zvláště v pomalé síti. Ale už je to dávno a minulý týden se mě Erin Stellato zeptala, jestli jsem to někdy formálně zdokumentoval. Nemám, takže tady. Vezmeme si velmi jednoduchou smyčku, kde milionkrát aktualizujeme proměnnou tabulky:

SET NOCOUNT OFF;
 
DECLARE @i INT = 1;
DECLARE @x TABLE(a INT);
INSERT @x(a) VALUES(1);
 
SELECT SYSDATETIME();
 
WHILE @i < 1000000
BEGIN
  UPDATE @x SET a = 1;
  SET @i += 1;
END
 
SELECT SYSDATETIME();

Pár věcí, kterých si můžete všimnout:

  • Podokno zpráv je zahlceno výskyty (1 row(s) affected) zpráva:

  • Počáteční SELECT SYSDATETIME(); se zobrazí v podokně výsledků až po dokončení celé dávky. Je to kvůli záplavám.
  • Spuštění této dávky trvalo asi 21 sekund.

Nyní to zopakujme bez DONE_IN_PROC zpráv, změnou SET NOCOUNT OFF; na SET NOCOUNT ON; a spusťte jej znovu.

Zatímco podokno zpráv již nebylo zahlceno zprávami ovlivněnými řádky (řádky), dávka stále trvala ~21 sekund.

Pak jsem si řekl, počkej chvíli, vím, co se děje. Jsem na místním počítači bez zapojení sítě, používám sdílenou paměť, mám pouze SSD a kapky a kapky RAM…

Zopakoval jsem tedy testy pomocí své místní kopie SSMS proti vzdálené Azure SQL Database – Standard, S0, V12. Tentokrát dotazy trvaly mnohem déle, a to i po snížení počtu iterací z 1 000 000 na 100 000. Ale opět nebyl žádný hmatatelný rozdíl ve výkonu, zda DONE_IN_PROC zprávy byly nebo nebyly odesílány. Obě dávky trvaly asi 104 sekund a to bylo opakovatelné v mnoha iteracích.

Závěr

Po léta jsem fungoval v dojmu, že SET NOCOUNT ON; byla kritickou součástí každé výkonnostní strategie. To bylo založeno na pozorováních, která jsem učinil v pravděpodobně jiné době, a dnes je méně pravděpodobné, že se projeví.

To znamená, že budu nadále používat SET NOCOUNT ON , i když na dnešním hardwaru není znatelný rozdíl ve výkonu. Stále velmi silně cítím minimalizaci síťového provozu, kde je to možné. Měl bych zvážit implementaci testu, kde mám mnohem omezenější šířku pásma (možná má někdo AOL CD, které by mi mohl půjčit?), nebo mít počítač, kde je množství paměti nižší než limity výstupní vyrovnávací paměti Management Studio, abych se ujistil, že nepředstavuje potenciální dopad v nejhorších scénářích. Mezitím to sice nemusí změnit vnímaný výkon vaší aplikace, ale stále může vaší peněžence pomoci tuto nastavenou možnost vždy zapnout, zejména v situacích, jako je Azure – kde vám mohou být účtovány poplatky za odchozí provoz.


  1. Vnitřní části sedmi druhů SQL Server – část 2

  2. Lomítko nebo žádné lomítko?

  3. SQL pro generování seznamu čísel od 1 do 100

  4. Oracle SQL escape znak (pro '&')