Real-Time materialized view

زمان اجرای دو پرس و جوی زیر را با هم مقایسه کنید:

SQL> set timing on

پرس و جوی اول:

SQL> select /*+FULL(TBL1)*/ count(*) from tbl1;

  COUNT(*)

———-

 176000000

Elapsed: 00:00:02.33

پرس و جوی دوم:

SQL> select id, count(*) count from tbl1 group by id;

        ID      COUNT

———- ———-

         2   35200000

         1  105600000

         3   35200000

Elapsed: 00:00:22.01

همانطور که می بینید، دستیابی به جدول tbl1 به صورت full table scan در زمان دو ثانیه انجام شده است(با فرض اجرای دستورflush buffer_cache) ولی محاسباتی که در دستور دوم مورد نیاز است، 20 ثانیه به زمان اجرای دستور اول، اضافه می کند!

حال اگر قرار باشد پرس و جوی شماره دو، به دفعات تکرار شود، شاید زمان اجرای آن چندان قابل قبول نباشد! با این فرض که درصدی خطا برای خروجی این پرس و جو، قابل اغماض باشد، می توان از این پرس و جو، materialized viewای را ایجاد نمود تا در بازه های زمانی معین، بروزرسانی شود و در نتیجه، خروجی مورد نظر، با صرف مدت زمان بسیار کمی، به کاربر برگردد:

create materialized view log on tbl1 with rowid (id,city) including new values;

create materialized view mv_nonreal

refresh fast on demand

enable query rewrite as select id, count(*) count from tbl1 group by id;

SQL> select * from mv_nonreal;

        ID      COUNT

———- ———-

         2   35200000

         1  105600000

         3   35200000

Elapsed: 00:00:00.05

همانطور که می بینید، در صورت استفاده از mv(materialized view) برای این پرس و جو، زمان اجرای دستور، به کسری از ثانیه تقلیل می یابد البته با اولین اجرای دستور dmlای بر روی جدول tbl1، mv، در حالت stale قرار خواهد گرفت و نیاز به بروزرسانی خواهد داشت در مورد شیوه های مختلف بروزرسانی، سابقا در همین سایت، مقاله ای ارائه شد(به مطلب mv رجوع بفرمایید) به همین جهت، از تکرار روشهای بروزرسانی MV در این نوشتار، پرهیز می کنیم. در همه روشهای بروزرسانی مطرح شده، امکان ارائه خروجی بروز، بدون بروزرسانی فیزیکی mvها امکان پذیر نبود به عبارت دیگر، جدول مربوط به mv، باید بروز شود تا خروجی بروز به کاربر نمایش داده شود.

در اوراکل 12cR2، ویژگی جدیدی ارائه شد که بدون نیاز به بروزرسانی فیزیکی mv، خروجی بروز را به کاربر نمایش می دهد با کمک این ویژگی جدید که Real-Time Materialized View نام دارد به صورت انلاین و به عبارت بهتر، on the fly، می توان خروجی بروز را به کاربر نمایش داد(البته بدون انکه mv مورد نظر، بروزرسانی شود!) این کار با پیوند جدول mv و تغییرات ثبت شده در mv log انجام می شود که در مثال زیر، با جزییات بیشتری به ان خواهیم پرداخت.

در دستور زیر، mv جدیدی بر روی جدول tbl1 ایجاد خواهد شد که عبارت enable on query computation هم در متن ان قابل مشاهده می باشد:

create materialized view mv_real

refresh fast on demand

enable on query computation

enable query rewrite as select id, count(*) count from tbl1 group by id;

بعد از ایجاد این mv، رکوردی را در جدول tbl1 درج می کنیم تا رفتار دو mv را با هم مقایسه کنیم:

insert into tbl1 values(1,’Tehran’);

commit;

 

select mview_name,staleness,on_query_computation from user_mviews;

MVIEW_NAME STALENESS ON_QUERY_COMPUTATION
MV_NONREAL STALE N
MV_REAL STALE Y

 

SQL> select * from mv_real;

        ID      COUNT

———- ———-

         2   35200000

         1  105600000

         3   35200000

Elapsed: 00:00:00.00

SQL> select * from mv_nonreal;

        ID      COUNT

———- ———-

         2   35200000

         1  105600000

         3   35200000

Elapsed: 00:00:00.00

همانطور که می بینید، هیچ کدام از این دو mv، خروجی بروز را به کاربر نشان نداده اند!!! نکته اینجاست که برای نمایشreal time خروجی، باید از هینتی به نام fresh_mv استفاده کرد:

SQL> select  /*+ fresh_mv */* from mv_real;

        ID      COUNT

———- ———-

         2   35200000

         3   35200000

         1  105600001

Elapsed: 00:00:00.00

پس با اضافه کردن این هینت، خروجی بروز قابل مشاهده می باشد. همچنین با اجرای شکل اولیه دستور، query rewrite انجام خواهد پذیرفت که با مشاهده نقشه اجرایی این پرس و جوها، به تفاوت انها، پی خواهیم برد.

پرس و جوی اول(شکل اول دستور – بدون mv):

select /*+opt_param(‘query_rewrite_enabled’,’false’) */ id, count(*) count from tbl1 group by id;

نکته:با هینت opt_param(‘query_rewrite_enabled’,’false’)، از انجام عمل query rewrite جلوگیری به عمل خواهد امد.

پرس و جوی دوم(mv non-real):

select * from mv_nonreal;

پرس و جوی سوم(mv real-time):

select id, count(*) count from tbl1 group by id; =>(query_rewrite_enabled=TRUE)

OR

select  /*+ fresh_mv*/* from mv_real;

در صورتی که قصد فعال یا غیرفعال کردن این ویژگی را برای یک mv داشته باشیم، می توانیم از دستورات زیر استفاده کنیم:

alter materialized view mv_real disable on query computation;

alter materialized view mv_real enable on query computation;

نکته 1: برای استفاده از این ویژگی، پارامتر QUERY_REWRITE_INTEGRITY باید به یکی از دو مقادیر enforced و TRUSTED تنظیم شده باشد.

نکته 2: این ویژگی محدودیتهایی را هم به همراه دارد نظیر عدم استفاده توامان این قابلیت به همراه refresh on commit، db-link و …

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

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