Real-Time Statistics در اوراکل 19c

تا قبل از اوراکل نسخه 12c، اجرای دستورات DMLای بر روی یک جدول(به هر دو روش Conventional و Direct-path)، منجر به بروزرسانی آمار(Statistics) آن جدول نمی شد و جمع آوری انلاین آمار، صرفا در زمان ساخت ایندکس قابل انجام بود.

در نسخه 12c بهبود مختصری در این زمینه رخ داد که بر اساس آن، همراه با عملیات Bulk load بر روی یک جدول، آمارهای آن جدول هم به صورت انلاین بروز خواهد شد اما کماکان برای دستورات DMLای که به صورت CONVENTIONAL اجرا می شوند، تغییری در آمارهای جدول ایجاد نمی شود.

یکی از قابلیتهای جدید اوراکل نسخه 19c، ویژگی Real-Time Statistics می باشد که قابلیت بروزرسانی آنلاین بعضی از آمارهای مهم را همراه با اجرای دستورات DMLای، فراهم خواهد کرد.

این قابلیت جدید، صرفا بهبودی را در روند جمع آوری آمار ایجاد می کند و ساختار قبلی جمع آوری آمار، در این نسخه از اوراکل هم کماکان به شکل قبل پابرجاست.

در مثال زیر، با جزییات بیشتری به این ویژگی جدید اوراکل می پردازیم.

مثال: با دستور زیر، جدول mytbl را ایجاد می کنیم:

SQL>create table usef.mytbl (id number,name varchar2(100));

Table created

همانطور که انتظار می رود، آماری برای این جدول ثبت نشده است:

SQL> select table_name, num_rows,last_analyzed from dba_tab_statistics where table_name=’MYTBL’;

SQL> select table_name, column_name, low_value, high_value,notes,LAST_ANALYZED from dba_tab_col_statistics where table_name=’MYTBL’;

no rows selected

با دستور زیر، به صورت دستی، آمار مربوط به این جدول را بروز می کنیم:

SQL> exec DBMS_STATS.GATHER_TABLE_STATS(‘USEF’, ‘MYTBL’, METHOD_OPT=>’FOR ALL COLUMNS SIZE 5′);

PL/SQL procedure successfully completed

SQL> select table_name, num_rows,last_analyzed from dba_tab_statistics where table_name=’MYTBL’;

قصد داریم 1000 رکورد را در این جدول درج کنیم:

SQL> BEGIN

  2     for i in 1..1000 loop

         insert into usef.MYTBL values(i,’DBA’);

  4     end loop;

  5  END;

  6  /

PL/SQL procedure successfully completed

با رجوع به ویوی dba_tab_statistics و dba_tab_col_statistics، آمار مربوط به این جدول را بازبینی می کنیم:

select owner,table_name, num_rows,last_analyzed,notes from dba_tab_statistics where table_name=’MYTBL’;

select column_name, low_value, high_value,notes,LAST_ANALYZED from dba_tab_col_statistics s where notes = ‘STATS_ON_CONVENTIONAL_DML’ and table_name=’MYTBL’;

با مشاهده مقدار ستون NOTES در این دو ویو، خواهیم دید که آمار به صورت STATS_ON_CONVENTIONAL_DML بروز شده است البته آمار جمع آوری شده، به صورت بازه ای، به دیسک منتقل می شود و استفاده از دستور زیر هم می تواند در مواردی برای انتقال این اطلاعات از حافظه به دیسک موثر باشد:

SQL> EXEC DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;

PL/SQL procedure successfully completed

عملیات FULL TABLE SCAN برای جدول mytbl، با هزینه ای برابر با 3  انجام خواهد شد:

SQL> select count(*) from mytbl;

همچنین در صورت درج 1 میلیون رکورد دیگر در این جدول، خواهیم دید که این plan به صورت خودکار تغییر خواهد کرد:

BEGIN

   for i in 1..1000000 loop

      insert into usef.MYTBL values(i,’DBA’);

   end loop;

END;

/

در plan زیر می بینید که هزینه FULL TABLE SCAN این جدول، به 550 تغییر کرده است:

SQL> EXEC DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;

PL/SQL procedure successfully completed

SQL> select * from mytbl;

با دستور زیر هم خواهیم دید که از آمارهای جمع آوری شده(در طول اجرای عملیات dmlای)، در زمان اجرای دستور استفاده خواهد شد:

SQL> select count(*) from usef.mytbl;

  COUNT(*)

———-

   1000000

SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(format=>’TYPICAL‘));

Plan hash value: 404528059

——————————————————————–

| Id  | Operation          | Name  | Rows  | Cost (%CPU)| Time     |

——————————————————————–

|   0 | SELECT STATEMENT   |       |       |   550 (100)|          |

|   1 |  SORT AGGREGATE    |       |     1 |            |          |

PLAN_TABLE_OUTPUT

——————————————————————————–

|   2 |   TABLE ACCESS FULL| MYTBL |  1001K|   550   (1)| 00:00:01 |

——————————————————————–

Note

   – dynamic statistics used: statistics for conventional DML

قابلیت Real-Time Statistics را می توان با کمک پارامتر مخفی optimizer_gather_stats_on_conventional_dml_، و در دو سطح system و session غیرفعال کرد. همچنین می توان با کمک هینت NO_GATHER_OPTIMIZER_STATISTICS، این قابلیت را در سطح یک دستور، غیرفعال نمود.

ارتباط با نویسنده مطلب:vahidusefzadeh@ کانال تخصصی اوراکل و لینوکس: OracleDB@

Comment (1)

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد.