pirmdiena, 2010. gada 20. septembris

Determinētu funkciju izmantošana

Rakstā īsi aprakstīts kas ir determinētas un kas ir nedeterminētas funkcijas. Mazliet garāk rādīts un skaidrots kā determinētu funkciju izmantošana uzlabo (var uzlabot) ātrdarbību.

Determinētas funkcijas (Deterministic functions) ir funkcijas, kas pie vienādiem ieejas parametriem vienmēr atgriezīs tos pašus rezultātus. Piemēram, funkcija „Len”, kas nosaka teksta garumu, vienmēr apgalvos, ka teksts „Jā” ir ar garumu divi.

Nedeterminētas funkcijas (Nondeterministic functions) ir funkcijas, ka pie vienādiem ieejas parametriem (ja funkcijai ir ieejas parametri) var atgriezt savādākus rezultātus. Piemēram, funkcija GetDate() katrā izpildes reizē atgriezīs citus rezultātus (tas arī ir iemesls, kāpēc uz aprēķinātām kolonnām kas izmanto nedeterminētas funkcijas nevar uzlikt indeksu vai pārveidot par patstāvīgām aprēķinātām kolonnām).

Vairāk par determinētām funkcijām var palasīt šeit.

Kāpēc censties panākt, lai funkcija būtu determinēta?
Optimizācijai- izsaucot determinētu funkciju ar tiem pašiem parametriem- SQL Server var izdomāt, vai atkārtoti aprēķināt rezultātu, jeb arī izmantot iepriekš iegūto rezultātu. Respektīvi- ja funkcija bieži tiek saukta ar vienādiem ieejas parametriem, SQL Server visdrīzāk pieņems lēmumu saglabāt funkcijas rezultātu un to atkārtoti izmantot, kad nākamreiz vajadzēs iegūt funkcijas rezultātu ar tiem pašiem ieejas parametriem. (ilustrācija raksta beigās)

Tātad, piemēra funkcijas izveide:
Create Function dbo.TestFunc()
Returns int
As
Begin
    Return 5;
End
Pārbaude vai funkcija ir determinēta:
SELECT OBJECTPROPERTYEX(OBJECT_ID(N'dbo.TestFunc'), N'IsDeterministic')
Un lai cik jocīgi nebūtu- rezultātā tiks atgriezts "0", kas nozīmē, ka funkcija nav determinēta! Lai gan pēc  visa ir taču skaidrs, ka izpildot dbo.TestFunc() atgriezts tiks vienmēr "5"!

Āķis ir tajā, ka jāizmanto "With SchemaBinding", kas nosaka, ka neviens objekts, kas tiek izmantots funkcijā nevar tikt mainīts vai dzēsts.

Tātad, veidojam vēlreiz (no sākuma jādzēš iepriekš izveidotā, ja tādu izveidojāt):
Create Function dbo.TestFunc()
Returns int
with schemabinding
As
Begin
    Return 5;
End
Atkārtoti pārliecinoties vai funkcija ir determinēta- rezultāts būs "1" , kas nozīmē, ka ir.
Ilustrācijai izpildes plāns gadījumā, ja nav norādīts "With schemabinding" un SQL Server izmanto "drošo" pieeju veidojot izpildes plānu un pieņem, ka mūsu izveidotā funkcija var atgriezt dažādus rezultātus. Un kā zemāk redzams- notiek aprēķins.

Savukārt ja ir norādīts "With schemabinding" un SQL Serveris ir drošs, ka funkcija tiešām vienmēr atgriezīs tos pašus rezultātus. Zemāk redzams- aprēķins nenotika un jau pēc izpildes plāna redzams, ka vaicājums ir efektīvāks.

Nav komentāru:

Ierakstīt komentāru