SQLShack (Magyar)

Bevezetés

A relációs adatbázisokban a műveletek sorhalmazon történnek. Például egy SELECT utasítás egy sorkészletet ad vissza, amelyet eredményhalmaznak hívunk. Néha az alkalmazáslogikának egyszerre egy sorral kell dolgoznia, nem pedig a teljes beállított eredmény egyszerre. A T-SQL-ben ennek egyik módja a kurzor használata.

Ha programozói ismeretekkel rendelkezik, akkor valószínűleg a FOR vagy a WHILE ciklust használná, hogy egyszerre egy elemet ismételjen, tegyen valamit az adatok és a munka elkészült. A T-SQL-ben a CURSOR hasonló megközelítés, és előnyösebb lehet, mert ugyanazt a logikát követi. De ne feledje, kövesse ezt az utat, és baj következhet.

Vannak olyan esetek, amikor a CURSOR használata nem okoz akkora rendetlenséget, de általában kerülni kell őket. Az alábbiakban bemutatunk néhány példát, amikor a CURSOR használata teljesítményproblémákat okoz, és látni fogjuk, hogy ugyanaz a munka sok más módon is elvégezhető.

A bemutató céljára az AdventureWorks2012 adatbázist fogjuk használni, és tegyük fel, hogy néhány adatot szeretnénk szerezni. táblázat, minden olyan termékhez, amelynek gyártása kevesebb, mint egy napot igényel, vagyis a táblázatból.

Kurzorpélda

Kezdjük egy KURZOR használatával, és írjuk be a következő szintaxist:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

AZ AdventureWorks2012 HASZNÁLATA
GO
DECLARE @id int
DEKLARÁLJ kurzorT kurzor
– HELYI STATIKUS
– HELYI FAST_FORWARD
– HELYI VISSZA CSAK FORWARD_ONLY
FOR
SELECT ProductId
FROM AdventureWorks2012.Production.Product
WHERE DaysToManufacture < = 1
kurzor NYITÁSA
KÖVETKEZTETÉS A kurzorTÓL @ @id-be
Mialatt @@ FETCH_STATUS = 0
BEGIN
SELECT * FROM Production.ProductInventory
WHERE ProductID = @ id
KÖVETKEZIK A kurzorTÓL A @ID-be

END
ZÁR kurzorT
KurzorTÖRLÉS / div>

Rövid kávészünet után , a lekérdezés befejezte a végrehajtást, 833 sort adott vissza az alább látható idő alatt. Fontos megemlíteni, hogy a fenti szintaxisok csak bemutató célokat szolgálnak, és nem végeztem el indexhangolást a dolgok felgyorsítása érdekében.

A kurzor végrehajtásakor két lépésünk van. Az első lépés, a pozicionálás, amikor a kurzor egy sorra állítja a pozícióját az eredményhalmazból. A második lépés, a visszakeresés, amikor az adott sorból kapja az adatokat a FETCH nevű műveletben.

Példánkban a kurzor az első SELECT által visszaadott első sorra állítja be a pozícióját, és lekéri a @ID változó WHERE feltételének megfelelő ProductID értéket. Ezután a második SELECT a változó értékével használja az adatokat. és a következő sor beolvasásra kerül. Ezeket a műveleteket addig ismételjük, amíg nincs több sor, amellyel dolgozni lehet.

Végül a CLOSE szintaxis felszabadítja az aktuális eredményhalmazt, és eltávolítja a zárakat a kurzor által használt sorokból, a DEALLOCATE pedig eltávolítja a kurzor hivatkozását.

A bemutató táblázataink viszonylag kicsiek, nagyjából 1000-et tartalmaznak és 500 sor. Ha milliónyi sorral rendelkező táblázatokon kellene áttekintenünk, ez jelentős ideig tart, és az eredmények nem tetszenek nekünk.

Adjunk még egy esélyt a kurzorunknak, és tegyük le a megjegyzést a –LOCAL STATIC sorról. Sok argumentum használható a kurzor definíciójában, erről a linken található CURSOR Arguments, de most koncentráljunk arra, hogy mit is jelent ez a két szó.

Amikor megadjuk a LOCAL kulcsszót, a kurzor hatóköre lokális a kötegben, amelyben létrehozták, és csak ebben a hatókörben érvényes. A köteg végrehajtásának befejezése után a kurzor automatikusan elosztásra kerül. A kurzor hivatkozhat tárolt eljárással, triggerrel vagy egy kötegelt helyi kurzor változóval.

A STATIC kulcsszó ideiglenes másolatot készít a kurzor által a tempdb-ben használt adatokról egy ideiglenes táblában. . Itt van néhány gekánk. A STATIC kurzor csak olvasható, és pillanatkép kurzornak is nevezik, mert csak a nyitás időpontjától kezdve működő adatokkal működik, vagyis nem jeleníti meg az adatbázisban végrehajtott változásokat a kurzor.Alapvetően a kurzor nyitása után végrehajtott frissítések, törlések és beillesztések nem lesznek láthatók a kurzorok eredményhalmazában, hacsak nem zárjuk be és nem nyitjuk meg újra a kurzort.

Vegye figyelembe ezt az argumentumok használata előtt, és ellenőrizze, hogy megfelel-e az Ön igényeinek. De nézzük meg, hogy a kurzorunk gyorsabb-e. Az alábbiakban megkapjuk az eredményeket:

A 12 másodperc sokkal jobb, mint 4 perc és 47 másodperc, de ne feledje, hogy a fentiekben ismertetett korlátozások.

Ha a szintaxist ezzel az argumentummal futtatjuk LOCAL READ_ONLY FORWARD_ONLY, ugyanazokat az eredményeket kapjuk. A READ_ONLY FORWARD_ONLY kurzor csak az első sorból az utolsóig görgethető. Ha hiányzik a STATIC kulcsszó, a kurzor dinamikus és dinamikus tervet használ, ha rendelkezésre áll. De vannak olyan esetek, amikor a dinamikus terv rosszabb, mint a statikus.

Mi történik, ha megszüntetjük a –LOCAL FAST_FORWARD megjegyzést?

A FAST_FORWARD egyenértékű a READ_ONLY és a FORWARD_ONLY kurzorral, de képes a jobb terv kiválasztására statikus vagy dinamikus közül.

Úgy tűnik, hogy a LOCAL FAST_FORWARD a legjobb választás a rugalmasság miatt. válasszon statikus vagy dinamikus terv közül, de a FORWARD_ONLY szintén nagyon jó munkát végez. Bár mindkét módszerrel átlagosan 12 másodperc alatt értük el az eredményt, ezeket az érveket megfelelően tesztelni kell, mielőtt kiválasztanánk az egyiket.

Számos módja van annak, hogy ugyanazt az eredményt elérjük, sokkal gyorsabban és kevesebb hatással van a teljesítményre.

Kurzor alternatíva

Az egyik módszer a JOIN-t használja, és amint a következőkben láthatjuk, az eredmények lényegesen jobbak.

Először is, engedélyeznünk kell a statisztikai időt az SQL Server futtatási idejének mérésére, és két tábla között INNER JOIN-t kell létrehoznunk,. és. a ProductID oszlopban. Az EXECUTE gomb megnyomása után 330 ms alatt ugyanazokat az eredményeket produkáltuk, mint a kurzor módszer 04:47 ideje, és mosoly van az arcunkon.

1
2
3
4
5
6
7
8
9

HASZNÁLJA AdventureWorks2012
GO
A STATISZTIKA IDŐ BEÁLLÍTÁSA
SELECT * FROM Production.ProductInventory pinv-ként
BELSŐ CSATLAKOZÁS Produkció: pp
ON pinv.ProductID = pp.ProductID
WHERE pp.DaysToManufacture < = 1

Nem kell minden sort végigvezetnünk ahhoz, hogy megkapjuk, amire szükségünk van, nincs több hurokunk, no while záradék, no iter helyett inkább adatsorokkal dolgozunk, gyorsabban megszerezzük, amit akarunk, és kevesebb kódot írunk.

A kurzor megfelelő használata

Most, hogy láttuk, mekkora kár a kurzor képes megnézni egy példát, ahol felhasználhatjuk.

Tegyük fel, hogy az adatbázisból csak bizonyos táblákhoz szeretnénk kiválasztani a sorok méretét és számát. Ennek elérése érdekében megkapjuk az összes táblanevet az information_schema.tables kritériumai alapján, és egy CURSOR használatával végigvezetjük a táblák mindegyikét, és végrehajtjuk a tárolt sp_spaceused eljárást úgy, hogy egyszerre csak egy táblanevet adunk át a szükséges információk megszerzéséhez. .

Ugyanazt az AdventureWorks2012 adatbázist fogjuk használni, és az összes értékesítési séma tábláját megkapjuk, amely az ‘Sales’ nevet tartalmazza. Minden visszaküldött táblanévhez szeretnénk megnézni az information_schema.tables összes információját.

Az alábbiakban megtalálhatjuk a T-SQL szintaxist és a kapott eredményeket:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

AZ AdventureWorks2012 HASZNÁLATA

GO
DECLARE @TableName VARCHAR (50) – táblázat neve az “Sales” sémából
DECLARE @Param VARCHAR (50) – paraméter az “sp_spaceused” eljáráshoz
DECLARE db_kurzor kurzor FOR
– csak az “Értékesítés” táblát válassza es
TÁBLÁZAT KIVÁLASZTÁSA az information_schema.tables fájlból
WHERE TABLE_NAME, mint például a “% Sales%” és a TABLE_TYPE = “BASE TABLE”
NYITD A db_kurzort
KÖVETKEZŐK A db_kurzorból a következőbe: @TableName
Míg @ @ FETCH_STATUS = 0
BEGIN
–csatolja a változó minden egyes táblájának nevét, és adja át a tárolt eljárásnak
SET @ Param = “Értékesítés.”+ @ TableName
– végrehajtja a tárolt eljárást minden táblanévhez egyszerre
EXEC sp_spaceused @Param
KÖVETKEZŐ KÖVETKEZŐ A db_kurzorból INTO @TableName – megkapja a következő tábla nevét
END
ZÁR db_kurzor
A db_kurzor törlése

Ez az egyik módszer, ahol a CURSOR hasznos, ha egyes adatokat egyszerre soronként végigvezet, és megkapja a szükséges eredményt. Ebben a konkrét esetben a kurzor elvégzi a munkát anélkül, hogy befolyásolná a teljesítményt, és könnyen használható.

Következtetések

Itt van. Néhány kurzort használva bemutattunk néhány példát a jóra, a rosszra és a csúnyára. A legtöbb esetben használhatunk JOINS-t, még WHITE-ig, SSIS-t is csomagok vagy más alternatív módszerek segítségével ugyanazt az eredményt gyorsabban érheti el, kevesebb hatással van a teljesítmény kimenetére, és még kevesebb szintaxis sort is írhat.

Amikor az OLTP-környezettel és a feldolgozandó nagy adathalmazokkal foglalkoznak, a „CURSOR” szót nem szabad kimondani.

Az SQL-ben jó gyakorlat az adatkészletekkel végzett műveletek végrehajtása, nem pedig a gondolkodás programozott módon, iterációk vagy ciklusok használatával, mert ez a fajta megközelítés nem ajánlott, és nem is erre a célra szolgál. Az, hogy megpróbálja használni a programozási nyelvekből a FOR vagy FOREACH hurkokat, és ezt a logikát társítsa az SQL műveletekhez, akadályt jelent az igényeink megfelelő megoldásának megtalálásában. A halmazalapú műveletekre kell gondolnunk, nem pedig egyszerre egy sorra, hogy megszerezzük a szükséges adatokat.

A kurzorokat néhány alkalmazásban lehet használni sorosított műveletekhez, amint az a fenti példában látható, de általában meg kell kerülni kell, mert negatív hatást gyakorolnak a teljesítményre, különösen akkor, ha nagy adathalmazokon dolgoznak.

  • Szerző
  • Legfrissebb bejegyzések
DBA vagyok a Yazaki Component Technology-nál, 3 éves SQL Server-tapasztalattal.
Számítógép-mérnöki diplomám van, és rendelkezik ismeretekkel a .NET, a C # és a Windows Server területén is. Tapasztalatot szereztem a teljesítményhangolással és -figyeléssel, a T-SQL fejlesztésével, a biztonsági stratégiával, az adminisztrációval és az adatbázisok konfigurálásával kapcsolatban.
Lelkesen rajongok az informatikai dolgokért, a videojátékokért, a jó filmekért, és az elektro-house zene segít abban, hogy az irodában dolgozhassak. zajos.
Sergiu Onet összes üzenetének megtekintése

Sergiu Onet legújabb üzenetei (az összes megtekintése)
  • SQL Server kurzorok használata – Előnyök és hátrányok – 2016. március 23.

Write a Comment

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük