ایندکس BITMAP در اوراکل

در دیتابیس اوراکل انواع مختلفی از ایندکسها وجود دارند که از آنها به منظور بهبود کارایی دیتابیس استفاده می شود ولی هر کدام دارای کاربرد و ساختار متفاوت هستند. در این متن ایندکس های از نوع BITMAP که فقط در نسخه های ENTERPRISE اوراکل قابل تعریف و استفاده هستند را توضیح می دهیم.

 

ساختار BITMAP INDEX

زمانی که برای یک ستون از جدول، ایندکس BITMAP تعریف می شود یک ساختمان داده دو بعدی برای آن ستون ایجاد می گردد که تعداد سطرهای آن برابر با تعداد سطرهای جدول و تعداد ستون هایش برابر با تعداد مقادیر DISTINCT در ستون ایندکس گذاری شده خواهد بود. در این ساختمان داده از 0 و 1 برای مشخص نمودن وجود یا عدم وجود مقدارها استفاده می شود.

برای مثال اگر برای ستون GENDER در جدول زیر از BITMAP استفاده کنیم، ساختمان داده ایندکس به شکل زیر خواهد بود:

از آنجایی که فقط از 0 و 1 برای مشخص نمودن مقادیر استفاده می شود استفاده از این ساختمان داده سبب صرفه جویی در حافظه می شود. همچنین آرایه های بیتی به راحتی می توانند فشرده و ذخیره شوند.

زمانی که یک QUERY نیازمند استفاده از ایندکس BITMAP می باشد، ساختمان داده BITMAP به سرعت از حالت فشرده خارج شده و در BUFFER CACHE قرار می گیرد. سپس  تمام ROWID سطرهای مورد نیاز برای آن QUERY برگردانده می شوند. بنابراین در این ساختمان داده برای هر سطر، یک ROWID نیز ذخیره می شود.

در دیتابیس اوراکل اگر دو یا چند ستون BITMAP در یک جدول داشته باشیم برای QUERYهایی که شامل آن ستون ها می شوند به صورت اتوماتیک ساختمان داده BITMAPها به هم متصل می گردند و از عملیات منطقی بیتی بین آنها استفاده می شود که از لحاظ PERFORMANCE بسیار مناسب خواهد بود.

برای مثال در جدول زیر  سه ستون دارای BITMAP هستند بنابران می توان زنانی که متاهل هستند و سن آنها بین 35 تا 49 سال است را با سرعت بالا QUERY نمود زیرا از دستور AND منطقی بین بیت های این BITMAPها استفاده می شود.

در شکل زیر مشاهده می کنید که ROWIDهای مورد نیاز برای دو ستون مختلف از جدول باهم ادغام می شوند و در پاسخ نهایی QUERY برگردانده می شوند.

چه زمانی از ایندکس BITMAP استفاده کنیم؟

در موارد زیر استفاده از ایندکس های BITMAP  سبب بهبود PERFORMANCE می شود:

1.زمانی که داده های یک ستون از جدول دارای LOW CARDINALITY است یعنی داده های تکراری زیادی در آن ستون داریم. پیشنهاد می گردد تعداد مقدارهای DISTINCT حداکثر صد یا چند صد مورد باشند و اینکه تعداد تکرارها خیلی بیشتر از تعداد سطرها باشد در غیر این صورت استفاده از ایندکس های B-TREE به صرفه تر خواهد بود.  

برای مثال ستونی که فقط چند رنگ را برای چند میلیون ماشین مشخص می کند و یا ستون جنسیت افراد.

2.در دیتابیس های OLTP یا جدول هایی که عملیات DML روی آنها زیاد انجام می شود بهتر است از  ایندکس BITMAP استفاده نگردد زیرا در زمان تغییرات داده ها، بروزرسانی ساختمان داده BITMAP زمانبر و غیر بهینه خواهد بود. بنابراین معمولا در دیتابیس های DATA WAREHOUSE یا جدول های با بروزرسانی کم از BITMAP استفاده می شود.

3.زمانی که در QUERYها از ترکیب چندین ستون که شرایط 1 و 2 را دارند استفاده می شود بهتر است بجای ایندکس ترکیبی B-TREE برای تمام آن ستون ها به صورت مجزا از BITMAP استفاده نمود زیرا نتایج ستون های BITMAP به صورت اتوماتیک با هم ادغام می شوند.

4.برای MATERIALIZED VIEW هایی که در بازه زمانی خارج از پیک کاری بروز رسانی می شوند استفاده از BITMAP مناسب خواهد بود.

5.در QUERYهایی که وجود مقدار NULL را بررسی می کنند می توان از BITMAP استفاده کرد زیرا  این مقادیر توسط ایندکس BITMAP قابل دسترسی هستند ولی توسط ایندکسهای از نوع B-TREE قابل دسترس نیستند و عمل FULL TABLE SCAN انجام می شود.

 

نقاط ضعف BITMAP

در موارد زیر از لحاظ PERFORMANCE استفاده از ایندکسهای دیگر مانند B-TREE به صرفه تر خواهد بود:

1.در دیتابیس اوراکل اگر نیاز باشد یک مقدار از یک ستون که ایندکس BITMAP دارد بروزرسانی شود می بایست تمام سطرهای آن ستون LOCK شوند. بنابراین استفاده از BITMAP برای جدول هایی که تعداد تراکنش متوسط یا زیاد دارند از لحاظ PERFORMANCE به صرفه نیست و باعث مشکلات متعدد می شود.

2.سرعت QUERYهای محدوده ای (مانند عملگر BETWEEN) را نمی توان با ایندکس BITMAP بهبود داد. برای این QUERYها استفاده از ساختمان داده درختی (B-TREE) بهتر خواهد بود.

3.اگر اندازه جدول کوچک باشد دیتابیس اوراکل معمولا بجای استفاده از BITMAP از عمل FULL TABLE SCAN استفاده می کند.

4.برای ستون هایی که به PRIMARY KEY نزدیک هستند فضای حافظه زیادی مورد نیاز خواهد بود و استفاده از BITMAP به صرفه نیست.

 

یک مثال عملی از کارایی بهتر BITMAP

ساخت جدول با دو ستون همراه با  تولید و درج یک میلیون مقدار تصادفی:   

SQL> Create table milad.karbaran (shomare number(7), jens varchar2(4));

Table created

SQL>

SQL> Begin

      For i in 1..1000000

      Loop

      Insert into milad.karbaran

      values(i, decode(round(dbms_random.value),1,‘MARD’,(decode(round(dbms_random.value), 1, null, ‘ZAN’))));

      If mod(i, 100) = 0 then

      Commit;

      End if;

      End loop;

      End;

     /

PL/SQL procedure successfully completed

SQL>

SQL> select jens,count(*) from karbaran group by jens;

JENS      COUNT(*)

   —-          ———-

MARD      499532

                  250899

ZAN         249569

SQL>

بنابراین در این جدول، ستون jens دارای CARDINALITY پایین است و با فرض پایین بودن عملیات DML استفاده از ایندکس BITMAP برای QUERYهای شبیه به دستور زیر سبب دستیابی به COST کمتر و سرعت بالاتر می شود:

select count(*) from milad.karbaran t where t.jens=’MARD’;

مشاهده COST در حالت FULL TABLE SCAN :

SQL> explain plan for select count(*) from milad.karbaran t where t.jens=’MARD’;

Explained

SQL> select * from table(dbms_xplan.display);

مشاهده COST با استفاده از ایندکس B-TREE:

SQL> create index  jens_btreeind on milad.karbaran(jens);

Index created

SQL> explain plan for select /*+ index(karbaran jens_btreeind)*/count(*) from milad.karbaran t where t.jens=’MARD’;

Explained

SQL> select * from table(dbms_xplan.display);

مشاهده COST با استفاده از ایندکس BITMAP:

SQL> drop index jens_btreeind ;

Index dropped

SQL> create bitmap index jens_bitmapind on milad.karbaran(jens);

Index created

SQL> explain plan for select /*+ index(karbaran jens_bitmapind)*/count(*) from milad.karbaran t where t.jens=’MARD’;

Explained

SQL> select * from table(dbms_xplan.display);

 

Comments (5)

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *