Bosh sahifa Wiki Cursor

Cursor

Cursorquery natijasidagi rowlar to‘plami bo‘ylab bosqichma-bosqich yurish imkonini beradigan database mexanizmi. Cursor bir vaqtning o‘zida butun natijani application memory’siga yuklamasdan rowlarni ketma-ket olish yoki procedure ichida har rowga alohida ishlov berish uchun ishlatiladi.

Cursor atamasi database server cursor, client cursor va pagination cursor ma’nolarida ishlatilishi mumkin.

Result set holati

Oddiy query ko‘p row qaytaradi.

Cursor:

haqida holat saqlashi mumkin.

Client keyingi rowlar guruhini FETCHga o‘xshash amal bilan oladi.

Declare, open, fetch va close

Server-side cursor lifecycle’i odatda:

  1. declare;
  2. open;
  3. fetch;
  4. kerakli processing;
  5. close.

Soddalashtirilgan misol:

DECLARE user_cursor CURSOR FOR
SELECT id, email FROM users;

FETCH 100 FROM user_cursor;

Aniq syntax database’ga bog‘liq.

Server-side cursor

Natija serverda saqlanadi yoki query execution holati server tomonidan yuritiladi.

Afzalliklari:

Kamchiligi — connection va transaction uzoq vaqt ochiq qolishi mumkin.

Client-side cursor

Driver barcha natijani clientga olib, client memory’da cursor kabi boshqarishi mumkin.

Application API bir xil ko‘rinsa ham haqiqiy streaming bo‘lmasligi mumkin.

Katta queryda driver documentation va memory profiling tekshiriladi.

Fetch size

Har network round-tripda nechta row olinishi fetch size bilan boshqariladi.

Kichik fetch:

  • kam memory;
  • ko‘p network request.

Katta fetch:

  • ko‘p memory;
  • kam round-trip.

Row hajmi va processing tezligiga mos qiymat tanlanadi.

Forward-only cursor

Faqat oldinga yuradi.

Bu eng sodda va samarali cursor turi.

Katta export va stream processing uchun qulay.

Oldingi rowga qaytish kerak bo‘lsa application o‘zi saqlashi yoki boshqa cursor turi ishlatiladi.

Scrollable cursor

Oldinga, orqaga yoki aniq pozitsiyaga yurishi mumkin.

Bu qo‘shimcha server yoki client resursini talab qiladi.

Natija o‘zgarganda cursor eski snapshot yoki yangi rowlarni qanday ko‘rishi sensitivity modeliga bog‘liq.

Read-only cursor

Faqat natijani o‘qiydi.

Ko‘p query uchun shu model yetarli.

Updatable cursor rowni joriy pozitsiya orqali o‘zgartirishi mumkin, ammo portability va concurrency murakkabroq.

Cursor sensitivity

Cursor base table o‘zgarishlarini ko‘rishi yoki ko‘rmasligi mumkin.

Tushunchalar:

  • insensitive — snapshotga yaqin;
  • sensitive — o‘zgarishlarni ko‘rishi mumkin;
  • asensitive — implementation tanlaydi.

Aniq xatti-harakat database driver va isolation levelga bog‘liq.

Procedure cursor

Stored procedure query natijasini row-by-row qayta ishlash uchun cursor ochishi mumkin.

Masalan:

har invoice’ni olish
→ hisoblash
→ status yangilash

Bu procedural usul tushunarli bo‘lishi mumkin, ammo katta datasetda sekin.

Set-based SQL

Relational database butun rowlar to‘plami ustida ishlashga optimallashtirilgan.

Cursor loop:

har rowni o‘qi
har rowni update qil

o‘rniga bitta:

UPDATE ...
WHERE ...

statement ko‘pincha tezroq.

Cursor faqat set-based ifoda murakkab yoki external ketma-ket interaction talab qilganda ishlatiladi.

N+1ga o‘xshash xarajat

Cursor ichida har row uchun boshqa query bajarilsa katta round-trip va index lookup soni paydo bo‘ladi.

Masalan, 100 000 row uchun 100 000 qo‘shimcha query.

Join, bulk lookup yoki temporary table bilan querylar birlashtiriladi.

Transaction bilan bog‘liqlik

Server cursor ko‘pincha transaction doirasida mavjud.

Transaction commit qilinsa cursor yopilishi yoki saqlanishi mumkin.

Uzoq cursor:

  • eski snapshot;
  • vacuumga to‘sqinlik;
  • lock;
  • connection bandligi

yaratishi mumkin.

Holdable cursor

Ayrim database’larda commitdan keyin ham cursor davom etishi uchun holdable model mavjud.

Database natijani materializatsiya qilishi mumkin.

Bu storage va temp file xarajatini oshiradi.

Cursor va pagination

API pagination cursor — server-side SQL cursorning aynan o‘zi bo‘lishi shart emas.

Ko‘pincha u oxirgi sort keyni encode qiladi:

created_at + id

Keyingi query WHERE orqali davom etadi.

Bu stateless keyset pagination.

Cursor token

Tashqi clientga berilgan cursor:

saqlashi mumkin.

Token imzolanadi yoki server-side holatga reference qiladi.

Base64 tokenni o‘zgartirishdan himoya qilmaydi.

Resource cleanup

Cursor yopilmasa:

uzoq saqlanishi mumkin.

Driver context manager, finally yoki avtomatik close ishlatadi.

Connection poolga qaytarishdan oldin cursorlar yopiladi.

Failure

Network uzilsa server-side cursor yo‘qolishi mumkin.

Application davom etish uchun:

  • oxirgi processed key;
  • checkpoint;
  • idempotent processing

saqlaydi.

Uzoq exportni boshidan boshlash shart bo‘lmaydi.

Cursor nomi

Server-side cursor session doirasida noyob nomga ega bo‘lishi mumkin.

Bir connection pool orqali parallel ishlaganda cursor nomlari collision qilmasligi kerak.

Driver ko‘pincha bu nomlarni avtomatik boshqaradi.

Batch commit

Millionlab rowni cursor bilan qayta ishlaganda bitta ulkan transaction o‘rniga checkpointli batchlar ishlatilishi mumkin.

Har batch oxirgi processed keyni saqlaydi.

Qayta ishga tushishda ayni keydan davom etish uchun operation idempotent bo‘ladi.

Ordering

Cursor qayta davom ettirilishi uchun query aniq va barqaror ORDER BYga ega bo‘ladi. Tartib unique tie-breaker bilan yakunlanmasa row o‘tkazib yuborilishi mumkin.

Bog‘liq tushunchalar

Database cursor, Result set, Server-side cursor, Fetch size, Forward-only cursor, Stored procedure, Set-based SQL, Keyset pagination, Transaction