SQL Server Fast Forward Cursors

hlasů
6

Je všeobecně známo, že je třeba se vyhnout používání kurzorů do uložených procedur, kde je to možné (nahrazen stanovena na základě logiky, atd). Užíváte-li případy, kdy potřebujete k iteraci přes některé údaje, a mohou dělat v pouze pro čtení způsobem, je rychlý posun vpřed (pouze pro čtení vpřed) kurzor víceméně neefektivní než říci while? Z mých výzkumů to vypadá, jako by možnost kurzor je obecně rychlejší a používá méně čte a čas cpu. Neudělal jsem žádnou rozsáhlé testování, ale je to to, co jiní najdou? Dělat kurzory tohoto typu (rychlý posun vpřed) provádět další režii, nebo zdroj, který by mohl být drahé, že nevím o.

Je všechny ty řeči o nepoužíváte kurzory opravdu o zamezení používání kurzory, kdy jsou k dispozici set-založené přístupy, a použití aktualizovatelné kurzory atd.

dík

Položena 31/08/2008 v 19:56
zdroj uživatelem
V jiných jazycích...                            


9 odpovědí

hlasů
17

Zatímco rychle vpřed kurzor má určité optimalizace SQL Server 2005, je to pravda, že jsou někde v blízkosti dotaz nastaveného založený z hlediska výkonu. Existuje jen velmi málo situací, kdy kurzor logika nemůže být nahrazena dotazem nastavenou na bázi. Kurzory bude vždy neodmyslitelně pomalejší, zčásti díky tomu, že budete muset držet přerušení popravu, aby doplnili své lokální proměnné.

Zde je několik odkazů, které by byly jen špičkou ledovce, pokud výzkum tohoto problému:

http://www.code-magazine.com/Article.aspx?quickid=060113

http://sqlblog.com/blogs/adam_machanic/archive/2007/10/13/cursors-run-just-fine.aspx

Odpovězeno 01/09/2008 v 22:20
zdroj uživatelem

hlasů
2

Můžete se vyhnout kurzory většinu času, ale někdy je to nezbytné.

Jen mějte na paměti, že FAST_FORWARD je dynamická ... FORWARD_ONLY můžete použít s statické kurzor.

Zkuste použít ji na problém Halloween, aby viděli, co se děje !!!

IF OBJECT_ID('Funcionarios') IS NOT NULL
DROP TABLE Funcionarios
GO

CREATE TABLE Funcionarios(ID          Int IDENTITY(1,1) PRIMARY KEY,
                          ContactName Char(7000),
                          Salario     Numeric(18,2));
GO

INSERT IGNORE  INTO Funcionarios(ContactName, Salario) VALUES('Fabiano', 1900)
INSERT IGNORE  INTO Funcionarios(ContactName, Salario) VALUES('Luciano',2050)
INSERT IGNORE  INTO Funcionarios(ContactName, Salario) VALUES('Gilberto', 2070)
INSERT IGNORE  INTO Funcionarios(ContactName, Salario) VALUES('Ivan', 2090)
GO

CREATE NONCLUSTERED INDEX ix_Salario ON Funcionarios(Salario)
GO

-- Halloween problem, will update all rows until then reach 3000 !!!
UPDATE Funcionarios SET Salario = Salario * 1.1
  FROM Funcionarios WITH(index=ix_Salario)
 WHERE Salario < 3000
GO

-- Simulate here with all different CURSOR declarations
-- DYNAMIC update the rows until all of then reach 3000
-- FAST_FORWARD update the rows until all of then reach 3000
-- STATIC update the rows only one time. 

BEGIN TRAN
DECLARE @ID INT
DECLARE TMP_Cursor CURSOR DYNAMIC 
--DECLARE TMP_Cursor CURSOR FAST_FORWARD
--DECLARE TMP_Cursor CURSOR STATIC READ_ONLY FORWARD_ONLY
    FOR SELECT ID 
          FROM Funcionarios WITH(index=ix_Salario)
         WHERE Salario < 3000

OPEN TMP_Cursor

FETCH NEXT FROM TMP_Cursor INTO @ID

WHILE @@FETCH_STATUS = 0
BEGIN
  SELECT * FROM Funcionarios WITH(index=ix_Salario)

  UPDATE Funcionarios SET Salario = Salario * 1.1 
   WHERE ID = @ID

  FETCH NEXT FROM TMP_Cursor INTO @ID
END

CLOSE TMP_Cursor
DEALLOCATE TMP_Cursor

SELECT * FROM Funcionarios

ROLLBACK TRAN
GO
Odpovězeno 08/12/2014 v 13:31
zdroj uživatelem

hlasů
2

„Pokud chcete ještě rychlejší než kurzor FAST FORWARD pak pomocí statické kurzor. Jsou rychlejší než rychlý posun vpřed. Není extrémně rychlejší, ale může změnit.“

Ne tak rychle! Podle společnosti Microsoft:. „Obvykle, když nastala tato konverze, typ kurzoru degradován na‚dražší‘typu kurzoru Obecně platí, že (FAST) pouze pro předávání kurzor je nejvíce výkonný, následuje dynamický, sadou klíčů a nakonec STATIC, který je obecně nejméně výkonnější.“

od: http://blogs.msdn.com/b/mssqlisv/archive/2006/06/23/644493.aspx

Odpovězeno 13/07/2010 v 18:06
zdroj uživatelem

hlasů
1

Tato odpověď doufá, že ke konsolidaci odpovědí k dnešnímu dni.

1) Je-li to vůbec možné, používá sada založená logika pro vaše dotazy, tj vyzkoušet a používat jen SELECT, INSERT IGNORE , UPDATEnebo DELETEs vhodnými FROMdoložek nebo vnořených dotazů - to bude téměř vždy rychlejší.

2) Je-li výše není možné, pak v SQL Server 2005+ FAST FORWARDkurzory jsou efektivní a fungují dobře a měly by být používány přednostně před while.

Odpovězeno 20/01/2009 v 14:57
zdroj uživatelem

hlasů
1

Lidé vyhýbají kurzoru, protože jsou obecně více obtížné psát než jednoduchý while, nicméně, zatímco smyčka může být drahé, protože si neustále výběru dat z tabulky, dočasné nebo jinak.

S kurzorem, která je jen pro čtení vpřed, jsou data uložena v paměti, a byl speciálně navržen pro vytváření smyček.

Tento článek zdůrazňuje, že průměrná kurzor spustí 50x rychleji než while.

Odpovězeno 31/08/2008 v 23:16
zdroj uživatelem

hlasů
0

Některé alternativy pomocí kurzoru:

WHILE smyčky Temp tablolar odvozené tabulky související výkazy poddotazy případu více výslechy Často lze dosáhnout funkce kurzoru s non-kurzoru technik.

Pokud jste si jisti, že je třeba se kurzor má být použit, je počet záznamů, které mají být zpracovány by měly být sníženy, jak je to jen možné. Jedním ze způsobů, jak toho dosáhnout, je, aby se záznamy, které mají být zpracovány nejprve do dočasné tabulky, nikoli původní tabulky, ale kurzor, který bude používat záznamy v tabulce temp. Použije-li se tato cesta se předpokládá, že počet záznamů v tabulce temp byla značně snížena ve srovnání s původní tabulky. S menším počtem záznamů, kurzor dokončí rychleji.

Některé vlastnosti kurzorové, které ovlivňují výkon, zahrnují:

FORWARD_ONLY: Podporuje předávání pouze kurzor z prvního řádku na konci FETCH NEXT. Není-li nastavena jako sady klíčů nebo statické, SELECT klauzule přehodnoceny při každém načtení je volána.

Staticky: Vytvoří dočasnou kopii vytvořených dat a používá se kurzorem. Tím se zabrání kurzoru před přepočítány pokaždé, když se nazývá, což zlepšuje výkon. To neumožňuje změnu typu kurzoru a změny tabulky se neprojeví při načtení se nazývá.

Sady klíčů: Cursored řádky jsou umístěny v tabulce pod tempdb a změny nonkey sloupcích se projeví při načtení se nazývá. Nicméně nové záznamy přidány do tabulky se neprojeví. Pomocí sady klíčů kurzoru SELECT není znovu vyhodnocen.

DYNAMIC: Všechny změny v tabulce se projeví v cursore. Kurzor se přehodnoceny při každém načtení je volána. Využívá mnoho prostředků a nepříznivě ovlivňuje výkon.

FAST_FORWARD: Kurzor je jednosměrná, jako FORWARD_ONLY, ale určuje kurzor jen pro čtení. FORWARD_ONLY je zvýšení výkonu a kurzor není reevaluated každý načíst. To poskytuje nejlepší výkon, pokud je to vhodné pro programování.

Optimistický: Tuto možnost lze použít k aktualizaci řádků v kurzoru. Pokud řádek je přitažené za vlasy a aktualizován, a druhý řádek je aktualizován mezi vynést a aktualizačních operací aktualizace kurzor operace se nezdaří. Je-li optimisticky Kurzor použita, které mohou provádět aktualizaci řádku, to by nemělo být aktualizován jiným procesem.

Poznámka: Není-li uvedeno cursore, výchozí hodnota je FORWARD_ONLY.

Odpovězeno 12/07/2018 v 09:01
zdroj uživatelem

hlasů
0

Chcete-li odpovědět na otázky původních Mile je ...

Fast Forward, Read Only, statické kurzory (laskavě známý jako „požární hadice kurzor“), jsou obvykle stejně rychle nebo rychleji než ekvivalentní Temp tabulky a while, protože takový kurzor není nic víc než Temp tabulky a while, který byl optimalizován tak trochu zákulisí.

Chcete-li přidat k tomu, co Eric Z. Beard zveřejněny na tomto tématu a dále odpovědět na otázku ...

„Jsou všechny ty řeči o nepoužíváte kurzory opravdu o zamezení používání kurzory, kdy jsou k dispozici set-založené přístupy, a použití aktualizovatelné kurzory atd.“

Ano. Až na několik málo výjimek, to zabere méně času a méně kódu k napsání správného set-založený kód, aby učinily totéž, co většina kurzory a má navíc tu výhodu, za použití mnohem méně zdrojů a obvykle běží mnohem rychleji, než kurzor nebo když smyčky. Obecně lze říci, s výjimkou některých administrativních úkolů, ale opravdu je třeba se vyhnout ve prospěch řádně písemného kódu nastaveného na bázi. Existují samozřejmě výjimky z každé „pravidlo“, ale v případě kurzory, zatímco smyčky a jiné formy RBAR, většina lidí může počítat výjimky na prstech jedné ruky, aniž by s využitím všech prstů. ;-)

K dispozici je také pojem „Skryté RBAR“. To je kód, který podle všeho bázi, ale ve skutečnosti není. Tento typ kódu „set-based“ je důvod, proč někteří lidé přijali RBAR metody a tvrdí, že jsou „OK“. Například, řešení běží celkový problém pomocí agregovaný (SUM) korelována sub-query s nerovností v něm vybudovat průběžný součet není ve skutečnosti set-založený v mé knize. Místo toho, že je to RBAR na steroidech, protože pro každý řádek vypočítané, musí opakovaně „dotek“ mnoho dalších řádků v množství n * (n + 1) / 2. Který je známý jako „Trojúhelníkový Join“ a je alespoň z poloviny tak špatný jako full Cartesian Připojit (Cross Připojit nebo „náměstí Připojit“).

Ačkoli MS učinil některá zlepšení v tom, jak kurzory pracovat, protože SQL Server 2005, termín „Fast Cursor“ je stále protimluv ve srovnání s dobře napsanými kód nastaven na bázi. Které také platí i v prostředí Oracle. Pracoval jsem s Oracle na krátkou 3 roky v minulosti, ale mým úkolem bylo provést zlepšení výkonu v existujícím kódu. Většina skutečně podstatným zlepšením byly realizovány, když jsem se převede kurzorů nastavit na bázi kódu. Mnoho pracovních míst, které dříve trvalo 4 až 8 hodin k provedení byl snížen na minuty a někdy sekund.

Odpovězeno 30/12/2012 v 23:47
zdroj uživatelem

hlasů
-2

Pokud chcete ještě rychlejší než kurzor FAST FORWARD pak pomocí statické kurzor. Jsou rychlejší než rychlý posun vpřed. Není extrémně rychlejší, ale může změnit.

Odpovězeno 18/09/2008 v 10:11
zdroj uživatelem

hlasů
-3

Dále jen ‚Best Practice‘, jak se vyhnout kurzory v SQL Server sahá až do SQL Server 2000 a dřívějších verzích. Přepsání motoru v SQL 2005 řešit většinu otázek spojených s problematikou kurzory, a to zejména se zavedením rychle vpřed možnost. Kurzory nejsou neccessarily horší než set-bázi a jsou používány značně a úspěšně v Oracle PL / SQL (loop).

Dále jen ‚všeobecně přijímaný‘, které se týkají byl platný, ale je nyní zastaralé a nesprávné - jít za předpokladu, že rychle vpřed kurzory se chovají tak, jak výrobce a provádět. Udělat nějaké testy a výzkum, založila svá zjištění o SQL2005 a později

Odpovězeno 01/09/2008 v 22:05
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more