Kursory – dlaczego tak je lubimy i dlaczego ich lepiej nie używajmy….

            Ostatnio na jednym z for tematycznych ktoś napisał, że szuka lepszego rozwiązania, bo zrobił operację na dużej bazie SQL Server za pomocą kursora i operacja dłużyła się w nieskończoność. Sprowokowało mnie to do napisania poniższego postu:

 Za co lubimy kursory?

            Można z niewielkim marginesem błędu powiedzieć, że im mniej mamy do czynienia z czystym sqlem i bazą danych tym bardziej jesteśmy skłonni używać kursorów.

1. Użycie kursora jest intuicyjne. Dla nas, czytających wiersz po wierszu, łatwo zrozumieć logikę gdzie pobieramy dany wiersz, robimy na nim co mamy do zrobienia, po czym bierzemy kolejny. Zdecydowanie łatwiej jest również taki kod zinterpretować i opisać co, w którym miejscu i na jakiej danej się dzieje.

2. Użycie kursora skraca czas napisania i testowania złożonego procesu. W większości przypadków jest tak, że mamy mniej lub bardziej gotowy system. Następuje konieczność zrobienia złożonej operacji. Jeśli mamy napisane procedury dokonujące atomowych operacji (insert encji, update wartości) to dlaczego nie wywołać tego jedno po drugim, zamknąć w kursor i niech leci „w kółko”. Dodatkowy argument to taki, że takie bloczki istnieją już w kodzie i przeszły testy, a więc ryzyko popełnienia błędu jest znacznie mniejsze.

3. Użycie logiki kursora jest zrozumiałe dla osób piszących obiektowo. W kursor możemy zamknąć określony byt. Taki kursor ma swoje atrybuty, które zmieniamy określonymi metodami i śmiało, naprzód, idziemy dalej! Skoro w języku obiektowym to działa to przecież musi to działać i w bazie danych.

4. Do prostego kursora nie potrzeba dobrej wiedzy z dziedziny SQL. Chcąc zliczyć w jakiejś tabeli rekordy które spełniają dany warunek lub inne dwa warunki jednocześnie przy równoległym występowaniu relacji w innej tabeli… piszemy złożony select kursor. W nim najpierw sprawdzimy pierwszy warunek, potem kolejny, a na koniec relację…

Wszystko prawda, tylko że za co NIE lubimy kursorów?

            SQL Server to nie .NET czy Java, a T-SQL to nie język obiektowy. Należy zwrócić uwagę, że są to różne technologie zaprojektowane do różnych celów.

Zupełnie off-topic przykład z życia wzięty:

Jesteśmy podatnikiem, wypełniamy PIT, mamy do wpisania NIP, PESEL, dane urzędu skarbowego, kwoty… jak to robimy? Pole po polu, kratka po kratce…

Jesteśmy prezesem szeregowym pracownikiem ZUSu. Mamy arkusz excela, a w nim PESELe ludzi. W kolejnych polach pusty NIP, adres do korespondencji, datę wpłaty ostatniej składki… Każdą z kolumn uzupełnimy sięgając do innego programu ewidencjonującego dane. Gratulacje dla tego kto uzupełniałby wszystkie kolumny w danym wierszu i dopiero wtedy szedł do kolejnego wiersza. Zdecydowanie prostszym wydaje się spisanie z jednego programu wszystkich NIPów, potem z drugiego wszystkich adresów itd. Logiczne, prawda?

Wróćmy do T-SQLa…

1. Kursor nie idzie w parze z wydajnością. W kursorze wielokrotnie czytamy dane z tych samych tabel, często nie dając szans bazie na użycie indeksów.

2. Użycie kursora powoduje ryzyko utraty kontroli nad bazą Standardowo tworzone kursory, bez dodatkowych klauzul, zakładają  lock na bazie. Powoduje to opóźnienia innych operacji, zakleszczenia i… agresję administratorów baz danych J

3. Kursory w przeważającej liczbie sytuacji są nieefektywne. Bazy danych są stworzone do agregacji danych, pracy na zbiorach, można powiedzieć do pracy „po kolumnach”. Wymuszanie na nich pracy po wierszach nie jest dobrym pomysłem.

Podsumowując: a może jednak kursor?

Nie używajmy kursorów jeśli nie musimy. Wiele problemów da się rozwiązać bez ich użycia… a jeśli jakiś problem wymaga użycia kursora? To używajmy go tylko tam gdzie musimy, z właściwą jego deklaracją, poświęcając możliwie wiele czasu jego optymalizacji.

pozdrawiam,

Podziel się na:
  • Google Bookmarks
  • RSS
  • Dodaj do ulubionych
  • email
  • Facebook
  • Twitter
  • Blogger.com
  • LinkedIn
  • Gadu-Gadu Live