Odstraňování potíží uložené procedury recompilation

Překlady článku Překlady článku
ID článku: 243586 - Produkty, které se vztahují k tomuto článku.
Rozbalit všechny záložky | Minimalizovat všechny záložky

Na této stránce

Souhrn

Tento článek se zabývá jeden konkrétní typ problému výkonu aplikace setkat s Microsoft SQL Server: recompilation spuštění uložené procedury. Pokud řešíte problém výkon, ale není jste zjistili, toto je přesné zdrojové váš problém, naleznete následujícím článku v databáze Microsoft Knowledge Base před pokračováním:

224587Postupy: Poradce výkonu aplikací se serverem SQL
Tento článek předpokládá, že jste použili danou článku zúžit rozsah problému a, že jste zachycené trasování SQL Server Profiler s konkrétní sloupce události a data v něm podrobné.

Další informace

Jakmile uživatel spustí uloženou proceduru, pokud již není k dispozici v mezipaměti, načte procedury SQL Server a zkompiluje plán dotazů. Kompilovaný plán je uložen v mezipaměti a je opakovaně podle následných volajícím uloženou proceduru, dokud některé akce nastane znehodnotit plán a vynutit recompilation. Recompilation plán uložené procedury může způsobit následující akce:
  • Použití klauzule WITH PŘEKOMPILOVAT v příkazu CREATE PROCEDURE nebo EXECUTE.
  • K odkazované objekty včetně přidání nebo odstranění omezení, výchozí nebo pravidla změn schématu.
  • Sp_recompile tabulky odkazuje postupu spuštěna.
  • Postup obnovení databáze obsahující postup nebo libovolné objekty odkazuje (Pokud provádíte operace křížový databáze).
  • Příčinou plán splatné z mezipaměti dostatečná činnosti serveru.
Tyto důvody pro recompiling uložená procedura existovat v dřívějších verzích a způsobila plán překompilovat před zahájením provádění procedury. V SQL Server 7.0 je zavedena nové chování mohou způsobit uložené procedury k překompilovat během spuštění. Toto nové chování zajišťuje Optimalizátor má vždy nejlepší možné plán pro každý konkrétní příkaz v rámci procedury. Recompilation spuštění uložené procedury může způsobit následující události:
  • Dostatečná procento změny dat v tabulce, na který odkazuje na uložené procedury.
  • Postup interleaves operace Data Definition Language (DDL) a zpracování dat Language (DML).
  • Postup provádí určité operace dočasných tabulek.
Podrobně dále v tomto článku je popsána každá z těchto příčin.

V některých případech náklady recompiling uložené procedury je více než výhodu odvozené z tím, zvláště pro velké procedury. Je velmi důležité Všimněte si, že při aktivaci recompilation celé dávky nebo postup je recompiled. To znamená, že je přímo úměrná velikosti postup nebo dávkové snížení výkonu. Další informace o tomto tématu naleznete v tématu "Transact-SQL tipy" v SQL Server Books Online.


Následující informace v tomto článku se zaměřuje na identifikující příčinu předkompilací spuštění uložené procedury a popisuje metody, můžete jim zabránit.

Nejlepší

Je nejvhodnější vlastníka Kvalifikovat názvy uložené procedury při spouštění procedury. To umožňuje lepší jasnost a snadnější použití existující plán provádění aktuálním uživatelem. Například pokud uživatel, který není vlastníkem databáze (dbo) spustí vlastněných dbo uložené procedury (nazývané myProc v tomto příkladu) v databázi pubs, použijte následující příkaz:
exec dbo.myProc
				
namísto to:
exec myProc
				
Tato technika vylučuje nejasnostem o dalších možných verze postupu podle různých vlastníci z hlediska kódování a údržby a také umožňuje SQL Server k více přímý přístup plán provádění určitého postupu.

SQL Server podle není Kvalifikační jméno vlastníka zadá kód kompilace a získá KOMPILACE lock postupu. Však nakonec Určuje nový plán není vyžadováno (za předpokladu použití dalších důvodů), a proto NOT překompilovat plán v tomto okamžiku kvůli nedostatku kvalifikace. Zvláštní krok v postupu získání zámku KOMPILACE však může způsobit konflikty blokování v závažné situacích. Odkazovat Q263889 INF: SQL blokování Splatné k uzamčení [[KOMPILACE]] Další podrobnosti o této situaci.

Pokud jste vlastníkem kvalifikovat volání procedury s owner.procedure, není nutné získat zámek kompilace tak snížena konflikty.

Identifikace a řešení problémů

Pokud jste tak již neučinili, naleznete následujícím článku databáze v Microsoft Knowledge Base podrobnosti o zachytávání dat Profiler pomoci analyzovat výkon systému:
224587Postupy: Poradce výkonu aplikací se serverem SQL

Zobrazení dat Profiler

SQL Server Profiler obsahuje událost SP:recompile můžete sledovat počet překompilování vyskytují. Kdykoli během spuštění znovu zkompiluje uložené procedury, dojde k události SP:recompile.
  • Skupina trasování Profiler podle třídy událostí

    1. V nabídce soubor klepněte na tlačítko Vlastnosti.
    2. Na kartě Sloupce dat pomocí tlačítka nahoru nejprve přesunout Třídy událostí a text pod nadpisem skupiny s Třída událostí. Pomocí tlačítka dolů odebrat všechny sloupce pod nadpisem skupiny.
    3. Klepněte na tlačítko OK.
    Zkontrolujte počet událostí SP:recompile.

    Rozbalte položku skupiny SP:recompile zobrazíte podrobnosti jednotlivých výskytů. Sloupci text událost označuje název uložené procedury recompiled. Více postupy jsou příčinou překompilování, budou seřazeni podle počet výskytů. Pokud máte velký počet událostí SP:recompile a dochází k vysokému zaměřit na procedury, které mají nejvyšší číslo překompilování řešení. Poznámka: systém ID procesu (SPID) a začátek události SP:recompile jedna instance určité uložené procedure(s) a postupujte podle následujících pokynů.

    Pokud uvidíte všechny události SP:recompile, ale stále dochází problém výkonu, naleznete v následujícím článku databáze Microsoft Knowledge Base:
    224587Postupy: Poradce výkonu aplikací se serverem SQL
  • Určit prohlášení se spustil událost překompilujte

    1. V nabídce soubor klepněte na tlačítko Vlastnosti.
    2. Na kartě Sloupce dat pomocí tlačítka dolů odebrat všechny sloupce pod nadpisem skupiny.
    3. Na kartě události odebrat všechny události kromě SP: počáteční, SP:StmtStarting, SP:recompile a SP: dokončeno. Pokud událost SP:StmtStarting není zachytit, lze nahradit SP:StmtCompleted ale nezahrnujte obě protože tím tak zdvojnásobí částka potřebujete projděte informace.
    4. Pokud jste určili konkrétní instanci recompilation uložené procedury k prověření můžete omezit data zobrazit určitým SPID a časového rámce výskytu pomocí kartě filtry.
    5. Klepněte na tlačítko OK.

    Událost SP:recompile bude aktivována přímo následující události SP:StmtStarted výkazu uložené procedury, která způsobila recompilation. Po dokončení události překompilujte uvidíte opakování události SP:StmtStarted označující provádění příkazu s nově vygenerované plánu.

    Zvažte následující příklad:
    use pubs
    go
    drop procedure RecompProc 
    go
    create procedure RecompProc as
    create table #t (a int)
    select * from #t
    go
    exec RecompProc
    						
    -li spustit tento kód Query Analyzer a výše události zobrazit v trasování Profiler, uvidíte následující sekvence:

    Zmenšit tuto tabulkuRozšířit tuto tabulku
    Třída událostiText
    SP: počátečníRecompProc
    SP:StmtStartingVytvoření tabulky # t (int)
    SP:StmtStartingVyberte * z # t
    SP:recompileRecompProc
    SP:StmtStartingVyberte * z # t
    SP: dokončenoRecompProc


    Můžete zjistit okamžitě, byla prohlášení, která způsobila recompilation:
    select * from #t
    						
    Protože zobrazí před a po události SP:recompile.

    Pokud měl zachycené pouze události SP:StmtCompleted, ale nikoli událostí SP:StmtStarting, SP:recompile zobrazí před prohlášení, která způsobila jako níže:

    Zmenšit tuto tabulkuRozšířit tuto tabulku
    Třída událostiText
    SP: počátečníRecompProc
    SP:recompileRecompProc
    SP:StmtCompletedVyberte * z # t
    SP: dokončenoRecompProc


    Uvidíte, že SP:recompile událost je aktivována před událostí SP:StmtCompleted "vyberte * z # t" výpis, který způsobil recompilation. To smysl, jako příkaz nelze dokončit dokud, po pro překompilujte je generován nový plán dotazů. Zbývající část Příklady v tomto článku použít událost SP:StmtStarting. Pokud zachytávání pouze události SP:StmtCompleted právě nezapomeňte zobrazit prohlášení po SP:recompile popsaným výše.

    Všimněte si, že pokud tuto konkrétní uloženou proceduru spustit vícekrát, budou znovu SQL Server, existující plán tohoto postupu. Událost překompilujte uvidíte pouze na první spuštění procedury nebo pokud přetažení a znovu vytvořit postup při každém spuštění skriptu. Důvod pro recompilation v tomto konkrétním případě je popsána v tomto článku v části "Předkompilací související s prokládání data definice Language (DDL) a data popisovačem Language (DML) Operations"; Toto je jednoduše příklad ke znázornění jak snadno určit, které výkazu způsobuje recompilation.

Předkompilací k vyřízení změny řádků

Pokud byl změněn dostatečná procento data v tabulce odkazuje uložené procedury od okamžiku, kdy byla generována původní plán dotazů, SQL Server překompilovat uložené procedury zkontrolujte, zda má plán na základě nejaktuálnější statistická data. Jako příklad, zvažte následující uložené procedury:
drop procedure RowModifications 
go
create procedure RowModifications as
-- assume SomeTable exists with the same definition as #t, 
-- and has over 1000 rows
create table #t (a int, b char(10))
select * from #t
insert #t select * from SomeTable
select count(*) from #t  where a = 37
go
exec RowModifications
exec RowModifications
				
druhé provádění procedury RowModifications, bude získáte následující události Profiler:

Zmenšit tuto tabulkuRozšířit tuto tabulku
Třída událostiText
SP: počátečníRowModifications
SP:StmtStartingVytvoření tabulky # t (int, b char(10))
SP:StmtStartingVyberte * z # t
SP:StmtStartingVložit výběr t # * z SomeTable
SP:StmtStartingVyberte count(*) z # t kde = 37
SP:recompileRowModifications
Automatické UpdateStatsa
SP:StmtStartingVyberte count(*) z # t kde = 37
SP: dokončenoRowModifications

Poznámka: První spuštění také zobrazit události SP:recompile pro "vyberte * z # t" výkazu. Důvod pro recompilation v tomto konkrétním případě je popsána v tomto článku v části "Předkompilací související s prokládání data definice Language (DDL) a data popisovačem Language (DML) Operations". Tento příklad zaměřit na SP:recompile zobrazeno výše, protože dochází při každém postupu provedeny.

V tomto příkladu "Vyberte count(*) z # t kde = 37" způsobí recompilation postup kvůli změnit počet řádků od byla vytvořena v tabulce. Přítomnost událost Automatického UpdateStats potvrzuje, že byl kvůli úpravy řádku recompilation. Sloupci text označuje sloupec, pro které byly upraveny statistické údaje.

Při vytvoření tabulky t # počet řádků je nula. Plán původní "vyberte * z # t" vyvinut s daný počet řádků, stejně jako plán dotazu "vyberte počet (*)". Však před provedeny "Vyberte count(*)" 1 000 nové řádky vloženy do tabulky t #. Protože se změnila dostatečné množství dat Optimalizátor znovu zkompiluje postupu zajistit, že zvolí nejefektivnější plán pro výkaz. Tento recompilation dojde na každém spuštění uložené procedury, protože kurzor 1 000 řádků bude vždy zobrazena jako významné dostatečně k důvod recompilation.

SQL Server používá k určení, zda má být plán recompiled algoritmus je stejné algoritmus použitý pro automatické aktualizace statistiky popsané v následujícím článku databáze Microsoft Knowledge Base:
195565INF: Jak SQL Server 7.0 a SQL Server 2000 Autostats práce
V příkladu výše je dostatečně malá, recompilation by není mít znatelný vliv na výkon uložené procedury. Však máte velký uložené procedury, která provádí podobné výsledné předkompilací více aktivit, můžete zaznamenat snížení výkonu.

Následující metody existují counteract předkompilací kvůli úpravy řádku:
  • Spusťte příkaz pomocí sp_executesql.
    Toto je upřednostňovaným způsobem. Příkazy proveden pomocí sp_executesql uložené procedury zkompilovány není jako součást uložené procedury plánu. Proto při provádění příkazu SQL Server bude volného použít existující plán v mezipaměti pro výkaz nebo vytvořit nový v době spuštění. Plán volání uložené procedury v obou případech je ovlivněn a nemá být recompiled.

    Příkaz EXECUTE bude mít stejný efekt; však není vhodné. EXECUTE pomocí příkazu není jako efektivní jako použití sp_executesql, protože neumožňuje pro parametrizace dotazu.

    Postup RowModifications dané nad lze zapsat na použijte sp_executesql následujícím způsobem:

    drop procedure RowModifications2 
    go
    create procedure RowModifications2 as
    set nocount on
    -- assume SomeTable exists with the same definition as #t, 
    -- and has over 1000 rows
    create table #t (a int, b char(10))
    select * from #t
    insert #t select * from SomeTable
    exec sp_executesql N'select count(*) from #t where a = @a', 
                       N'@a int', @a =  37
    go
    exec RowModifications2
    exec RowModifications2
    						

    Druhý provádění procedury RowModifications2 bude naleznete následující události Profiler:

    Zmenšit tuto tabulkuRozšířit tuto tabulku
    Třída událostiText
    SP: počátečníRowModifications2
    SP:StmtStartingVytvoření tabulky # t (int, b char(10))
    SP:StmtStartingVyberte * z # t
    SP:StmtStartingVložit výběr t # * z SomeTable
    SP:StmtStartingExec sp_executesql N'select count(*) z # t kde = @ ', int n'@a ', @ = 37
    SP: počáteční
    SP:StmtStartingVyberte count(*) z # t kde = @
    Automatické UpdateStatsa
    SP:StmtStartingVyberte count(*) z # t kde = @
    SP: dokončeno
    SP: dokončenoRowModifications2


    Všimněte si, že neexistují žádné události SP:recompile postup RowModifications2. Jsou dokončení SP: počáteční k SP: dokončeno volání události sp_executesql pro sloupec kontextu a událost Automatického UpdateStats. Však protože toto volání je mimo kontext uložené procedury, postup RowModifications2 nemusí v tomto případě recompiled.

    Další informace o použití sp_executesql uložené procedury v tématu "sp_executesql (T-SQL)" a "Použití sp_executesql" témata v SQL Server Books Online.
  • Použít sub-procedures spusťte příkazy, které jsou příčinou předkompilací.
    V tomto případě příkazu může způsobit stále recompilation, ale namísto recompiling velké volání uložené procedury, jej budou překompilovat pouze malé sub-procedure.
  • Použijte možnost ZACHOVAT PLÁNOVÁNÍ.
    Dočasné tabulky mají zvláštní pravidla týkající se předkompilací což v některých případech může být přísnější než výchozí algoritmus recompilation. Použít ZACHOVAT PLÁNOVAT možnost oslabíte práh dočasnou tabulku zpět na výchozí algoritmus. Další informace naleznete v tomto článku v části "Předcházení Recompilation podle Using the ZACHOVAT PLÁNOVAT Option".
Poznámka:RowModifications postup je velmi zjednodušený příklad procedury recompiled kvůli úpravy řádku. Zkontrolujte následující upozornění týkající se tohoto příkladu:

  • Ačkoli příkladu dočasné tabulky na uložené procedury odkazovat také trvalé tabulek platí tato situace. Pokud byl změněn dostatečné množství dat v odkazované tabulce, protože generovány plán dotazů, uložené procedury recompiled. Rozdíly v jak dočasných tabulek jsou považovány za pro účely recompilation jsou popsány v "Předcházení Recompilation podle Using the ZACHOVAT PLÁNOVAT možnost" části tohoto článku.
  • První spuštění dvou výše uvedených postupů také způsobit recompilation na první vyberte z dočasné tabulky t #. Důvody pro tento recompilation jsou uvedeny v části "Předkompilací související s prokládání data definice Language (DDL) a data popisovačem Language (DML) Operations" části tohoto článku.
  • "Vyberte count(*) z # t" příkaz byl použit v tomto příkladu, nikoli jednoduché "vyberte * z # t" výkazu. Chcete-li se vyhnout nadměrné předkompilací, SQL Server nepovažuje recompiling "trivial plány" (například výběrový * z tabulky) kvůli úpravy řádku.

Předkompilací k vyřízení prokládání Data Definition Language (DDL) a zpracování dat Operations Language (DML)

Pokud DDL operace jsou prováděny v rámci dávkové procedury nebo, procedury nebo dávkové je recompiled při nalezne první DML následné operace ovlivnění účastní DDL tabulky.

Zvažte následující příklad uložené procedury:
drop procedure Interleave 
go
create procedure Interleave as
-- DDL
create table t1 (a int)
-- DML
select * from t1
-- DDL
create index idx_t1 on t1(a)
-- DML
select * from t1
-- DDL
create table t2 (a int)
-- DML
select * from t2
go
exec Interleave
				
-li spustit tento kód Query Analyzer a výše události zobrazit v trasování Profiler, uvidíte následující sekvence:

Zmenšit tuto tabulkuRozšířit tuto tabulku
Třída událostiText
SP: počátečníProkládat
SP:StmtStartingVytvoření tabulky t1 (int)
SP:StmtStartingVyberte * z t1
SP:recompileProkládat
SP:StmtStartingVyberte * z t1
SP:StmtStartingVytvoření indexu idx_t1 na t1(a)
SP:StmtStartingVyberte * z t1
SP:recompileProkládat
SP:StmtStartingVyberte * z t1
SP:StmtStartingVytvoření tabulky t2 (int)
SP:StmtStartingVyberte * z t2
SP:recompileProkládat
SP:StmtStartingVyberte * z t2
SP: dokončenoProkládat


V tomto případě je uložená procedura recompiled třikrát během spuštění. Porozumět, proč tomu, zvažte, jak Optimalizátor vyvíjí plán uložené procedury:
  1. Během počáteční kompilace postupu tabulek t1 a t2 neexistují. Proto mohou být vytvořeny žádné plán dotazů odkazování na tyto tabulky. Musí být generovány v okamžiku spuštění.
  2. Jako první spustí proceduru, prvním krokem je vytvoření tabulky t1. Dalším krokem je výběr z tabulky t1--které je pro žádné plán. Postup je proto v tomto okamžiku recompiled vyvinout plán příkazu SELECT. Plán je generována po vytvoření indexu pro aktuální výběr z t1, stejně jako vybrat z t1. Žádné plánu mohou být generovány pro výběr z t2, protože t2 stále dosud neexistuje.
  3. Dalším krokem je vytvoření rejstříku t1. Následující, vyberte jiné provést na t1, které nyní má plán z první překompilujte. Však protože schématu t1 byla změněna, protože generován, že plán, postup musí být recompiled znovu generovat nový plán vyberte z t1. A protože t2 stále neexistuje, žádné plánu mohou být generovány pro výběr z t.
  4. Dále je vytvořena tabulka t2 a vyberte ze t2 provedeny. Protože žádné plán existuje pro výkaz, je postup recompiled konečný čas.
Tyto předkompilací vyskytnout v každé spuštění uložené procedury. Snížit předkompilací změnit postup proveďte všechny DDL operací nejdříve, následovaný operací DML znázorněno v následující:
drop procedure NoInterleave 
go
create procedure NoInterleave as
-- All DDL first
create table t1 (a int)
create index idx_t1 on t1(a)
create table t2 (a int)
-- Then DML 
select * from t1
select * from t1
select * from t2
go
exec NoInterleave 
exec NoInterleave
				
První spuštění procedury NoInterleave v Profiler zobrazí následující události:

Zmenšit tuto tabulkuRozšířit tuto tabulku
Třída událostiText
SP: počátečníNoInterleave
SP:StmtStartingVytvoření tabulky t1 (int)
SP:StmtStartingVytvoření indexu idx_t1 na t1(a)
SP:StmtStartingVytvoření tabulky t2 (int)
SP:StmtStartingVyberte * z t1
SP:recompileNoInterleave
SP:StmtStartingVyberte * z t1
SP:StmtStartingVyberte * z t1
SP:StmtStartingVyberte * z t2
SP: dokončenoNoInterleave


V tomto případě všechny příkazy DDL provést až front-end. Tento postup zkompiluje Optimalizátor následovně:
  1. Během počáteční kompilace postupu tabulek t1 a t2 neexistují. Proto mohou být vytvořeny žádné plán dotazů odkazování na tyto tabulky. Musí být generovány v okamžiku spuštění.
  2. První kroky postupu provádí jsou DDL operace vytváření tabulek t1 a t2, stejně jako index na t1.
  3. Dalším krokem je první vyberte z t1. Protože tento příkaz SELECT je žádné plán, postup recompiled. Protože existují všechny objekty, jsou generovány plány všech příkazů SELECT v postupu v tomto okamžiku.
  4. Zbytek procedury provede pomocí plánů generována. Protože existují odkazované objektů žádné změny, je není třeba překompilovat další postup.
Poznámka: Druhý a následné spuštění provést použít existující plán dotazů a mezipaměti a proveďte není výsledkem libovolné předkompilací vůbec. Postupy vytvoření, měnit nebo přetažení tabulky by změněna zajistit, aby byly všechny příkazy DDL umístěn na začátku postupu.

Splatné k některé dočasné tabulky operacím předkompilací

Použití dočasné tabulky uložené procedury může způsobit uložené procedury recompiled každém postupu provedeny.

Chcete-li se vyhnout, změnit uložené procedury, že splňuje následující požadavky:
  • Všechny příkazy, které obsahují název dočasné tabulky odkazovat dočasné tabulky vytvořené ve stejné uložené procedury a není v uložené proceduře volajícího nebo volaného nebo v řetězec proveden EXECUTE pomocí uložené procedury, příkazu nebo sp_executesql.
  • Všechny příkazy, které obsahují název dočasné tabulky syntakticky po zobrazí dočasnou tabulku v uložené proceduře nebo aktivační události.
  • Neexistují žádné příkazy DEKLAROVAT CURSOR, jehož příkazů SELECT odkazovat dočasné tabulky.
  • Všechny příkazy, které obsahují název dočasné tabulky předcházet libovolného příkazu DROP TABLE odkazující dočasné tabulky.

    Příkazy DROP TABLE nejsou potřeba pro dočasné tabulky vytvořené v uložené proceduře. Tabulky jsou vynechána automaticky po dokončení postupu.
  • Žádné příkazy vytvoření dočasné tabulky (například CREATE TABLE nebo SELECT... INTO) se zobrazí v příkazu toku řízení jako například IF... ELSE nebo WHILE.

Předcházení Recompilation pomocí ZACHOVAT možnost plán

Dočasná tabulka využití v rámci uložené procedury zavádí určitých dokáže pro Optimalizátor dotazu. V průběhu životnosti spuštění uložené procedury může výrazně lišit počet řádků a statistické informace v tabulkách. Chcete-li zajistit Optimalizátor používá nejlepší plán ve všech případech týkající se dočasných tabulek, byl vyvinut zvláštní algoritmus být více agresivní s předkompilací. Algoritmus je uvedeno, že pokud dočasné tabulky vytvořené pomocí uložené procedury změnila více než šesti časy, postup bude být recompiled při dalším příkazu odkazuje na dočasnou tabulku.

Zvažte následující příklad:
drop procedure useKeepPlan 
go
create procedure useKeepPlan as
create table #t (a int, b char(3))
select * from #t
-- Make greater than 6 changes to #t
insert #t values (1, 'abc')
insert #t values (2, 'abc')
insert #t values (3, 'abc')
insert #t values (4, 'abc')
insert #t values (5, 'abc')
insert #t values (6, 'abc')
insert #t values (7, 'abc')
-- Now reference #t
select count(*) from #t 
--option (KEEP PLAN)
go
exec useKeepPlan
exec useKeepPlan
				
v tomto případě se zobrazí následující události Profiler pro druhý spuštění:

Zmenšit tuto tabulkuRozšířit tuto tabulku
Třída událostiText
SP: počátečníuseKeepPlan
SP:StmtStartingVytvoření tabulky # t (int)
SP:StmtStarting -Sedm příkazy - vložení
SP:StmtStartingVyberte count(*) z # t1
SP:recompileuseKeepPlan
SP:StmtStartingVyberte count(*) z # t1
SP: dokončenouseKeepPlan

Postup recompiled na vyberte dojde po sedmi změny t # dočasné tabulky.

Tento agresivní recompilation je užitečné v případech, kde změny distribuční data dočasné tabulky může výrazně ovlivnit plán optimální dotaz pro výkaz odkazující ho. Však z velké postupy často upravovat dočasné tabulky, ale významné způsobem, předkompilací může způsobit pomalejší celkový výkon. Možnost ZACHOVAT PLÁNOVAT příkaz SELECT byla zavedena pro tuto situaci.

ZACHOVAT PLÁNOVÁNÍ eliminuje způsobeny více než šesti změny dočasných tabulek v rámci procedury předkompilací uložené procedury a vrátí zpět na standardní algoritmus recompilation kvůli úpravy řádku popsána výše v tomto článku v části "Změny předkompilací související s řádek". PLÁNOVÁNÍ ZACHOVAT nezabrání předkompilací zcela, jednoduše zabrání způsobená více než šesti změny dočasné tabulky odkazované v postupu. Ve výše uvedeném příkladu Pokud odebrat komentář z řádku "možnost (KEEP plán)" v uložené proceduře události SP:recompile nebude generován.

Pokud odebrat komentář z řádku "možnost (KEEP plán)" v kódu výše a spustit jej uvidíte následující události Profiler:

Zmenšit tuto tabulkuRozšířit tuto tabulku
Třída událostiText
SP: počátečníuseKeepPlan
SP:StmtStartingVytvoření tabulky # t (int)
SP:StmtStarting -Sedm příkazy - vložení
SP:StmtStartingVyberte možnost # t1 count(*) (ZACHOVAT PLÁNOVÁNÍ)
SP: dokončenouseKeepPlan


Poznámka: není žádná událost SP:recompile.

SET předkompilací k určité splatné výpisy spuštění uložené procedury

Následujících pět SET možností jsou ve výchozím nastavení ZAPNUTA:
  • ANSI_DEFAULTS
  • ANSI_NULLS
  • ANSI_PADDING
  • ANSI_WARNINGS
  • CONCAT_NULL_YIELDS_NULL
Pokud se provedení příkazu SET kterékoli z těchto možností nastavení OFF uložené procedury recompiled při každém jeho spuštění. Důvod pro toto je, že tyto možnosti změna může ovlivnit výsledek dotazu, který spustil recompilation.

Zvažte následující vzorový kód:
Use pubs
drop procedure test_recompile
go

create procedure test_recompile as
Set ANSI_DEFAULTS OFF
Select au_lname, au_fname, au_id from authors
where au_lname like 'L%'
--Option (Keep Plan)
Go
				
v tomto případě se zobrazí následující události SQL Profiler pro každé spuštění uložené procedury:
+---------------------------------------------------+
| Event Class     | Text                            | 
+---------------------------------------------------+
| SP:Starting     | test_recompile                  | 
+---------------------------------------------------+
| SP:StmtStarting | Set ANSI_DEFAULTS OFF           | 
+---------------------------------------------------+
| SP:StmtStarting | select au_lname, au_fname, au_id| 
+---------------------------------------------------+
| SP:Recompile    | test_recompile                  | 
+---------------------------------------------------+
| SP:StmtStarting | select au_lname, au_fname, au_id| 
+---------------------------------------------------+
| SP:Completed    | test_recompile                  | 
+---------------------------------------------------+
				
výměna SET možnost s některou z pěti výše uvedených možností zobrazit stejné výsledky. Také zde pomocí možnosti ponechat plán nebude pomoci vyhnout recompilation, protože příčinou recompilation je z příkazu SET.

Doporučeným způsobem, jak se vyhnout recompilation je použít kterýkoli z těchto pěti příkazu SET v uložené proceduře. Další informace naleznete v následujícím článku databáze Microsoft Knowledge Base:
294942PRB: CONCAT_NULL_YIELDS_NULL SET způsobuje uložené procedury překompilujte
Však jako nedoporučuje, spuštěn SET příkazu Obnovit možnost připojení stejnou hodnotu jako uloženou proceduru můžete také vyhnout překompilujte způsobem jej jako:
Set ANSI_DEFAULTS OFF

exec test_recompile
				
the SQL Profiler trasování bude zobrazovat žádné další události SP:recompile.

Následující tabulka uvádí některé běžné příkazy SET a zda změna příkazu SET v uložené proceduře způsobí překompilujte:
Zmenšit tuto tabulkuRozšířit tuto tabulku
Nastavte výpisPřekompilovat
Set quoted_identifierNO,
Sada arithabortANO
Sada ansi_null_dflt_onANO
Sada ansi_defaultsANO
Sada ansi_warningsANO
Sada ansi_paddingANO
Sada concat_null_yields_nullANO
Sada numeric_roundabortNO,
Set nocountNO,
Sada rowcountNO,
Sada xact_abortNO,
Sada implicit_transactionsNO,
Sada arithignoreNO,
Sada lock_timeoutNO,
Sada fmtonlyNO,

Odkazy

308737INF: Postup zjištění příčiny Recompilation událostí SP:recompile

Informace o pomocí serveru SQL Profiler, viz SQL Server Books Online.

Vlastnosti

ID článku: 243586 - Poslední aktualizace: 2. listopadu 2007 - Revize: 2.5
Informace v tomto článku jsou určeny pro produkt:
  • Microsoft SQL Server 7.0 Standard Edition
  • Microsoft SQL Server 2000 Desktop Engine (Windows)
  • Microsoft SQL Server 2000 Personal Edition
  • Microsoft SQL Server 2000 Developer Edition
  • Microsoft SQL Server 2000 Enterprise Edition
  • Microsoft SQL Server 2000 Standard Edition
Klíčová slova: 
kbmt kbinfo KB243586 KbMtcs
Strojově přeložený článek
Důležité: Tento článek byl přeložen pomocí software společnosti Microsoft na strojový překlad, ne profesionálním překladatelem. Společnost Microsoft nabízí jak články přeložené překladatelem, tak články přeložené pomocí software na strojový překlad, takže všechny články ve Znalostní databázi (Knowledge Base) jsou dostupné v češtině. Překlad pomocí software na strojový překlad ale není bohužel vždy dokonalý. Obsahuje chyby ve skloňování slov, skladbě vět, nebo gramatice, podobně jako když cizinci dělají chyby při mluvení v češtině. Společnost Microsoft není právně zodpovědná za nepřesnosti, chyby nebo škody vzniklé chybami v překladu, nebo při použití nepřesně přeložených instrukcí v článku zákazníkem. Společnost Microsoft aktualizuje software na strojový překlad, aby byl počet chyb omezen na minimum.
Projděte si také anglickou verzi článku:243586

Dejte nám zpětnou vazbu

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com