artarad_cursor_sharing

پارامتر CURSOR_SHARING

 

مقدمه
Cursor فضایی از حافظه (بخشی از Library Cache) است که اطلاعاتی نظیر متن دستور، طرح اجرایی ، اطلاعات آماری و … را در مورد دستورات SQL نگهداری می‌کند. هر دستور SQL یک Parent Cursor و یک یا چند Child Cursor دارد. درصورتی‌که درون دستور SQL از Bind Variables استفاده شده باشد، و این متغیرها هر بار مقادیر مختلفی را شامل شوند، Child Cursors مختلفی برای Parent Cursor ساخته می‌شود.


در این مقاله به بررسی پارامتر CURSOR_SHARING پرداخته می‌شود. این پارامتر اشتراک‌گذاری Child Cursors را در شرایطی که مقدار Bind Variables متفاوت باشند، کنترل می‌کند.
CURSOR_SHARING
متغیر CURSOR_SHARING از نوع پویا بوده و تغییر آن نیازی به راه‌اندازی مجدد پایگاه‌داده ندارد. این متغیر سه مقدار متفاوت زیر را می‌پذیرد.
EXACT
FORCE
SIMILAR
حال به تمایزهای این سه مقدار پرداخته می‌شود.
EXACT
درصورتی‌که مقدار پارامتر CURSOR_SHARING پایگاه‌داده برابر EXACT باشد؛ اگر یک دستور SQL همراه با literals مختلفی توسط کاربران مختلف اجرا شود، Parent Cursors متعددی ساخته می‌شود.
به مثال زیر که در کاربری hr اجرا شده است، توجه شود.

SQL> DROP TABLE test PURGE;
SQL> CREATE TABLE test
(
id1 NUMBER,
id2 NUMBER,
txt CHAR (5)
);

ابتدا یک جدول برای انجام آزمایش‌ها ایجاد می‌شود. دستور بالا نخست جدول مشابه را در صورت وجود حذف و سپس جدول موردنظر را ایجاد می‌کند.

سپس در ادامه با استفاده از دستورات زیر اقدام به ورود داده‌های آزمایشی به جدول می‌شود.

SQL> INSERT INTO test
VALUES (1, 1, ‘one’);
SQL> BEGIN
FOR i IN 1 .. 1000
LOOP
INSERT INTO test
VALUES (2, 2, ‘two’);

INSERT INTO test
VALUES (3, 3, ‘three’);
END LOOP;
END;
/
SQL> INSERT INTO test
SELECT *
FROM test
WHERE id1 = 3;
SQL> COMMIT;

حال بر روی ستون‌های ID1 و ID2 به‌صورت مجزا Index ایجاد می‌شود.

SQL> CREATE INDEX test_idx1
ON test (id1);
SQL> CREATE INDEX test_idx2
ON test (id2);

در انتها برای اطمینان از صحت دستورات بالا Query زیر اجرا می‌شود.

SQL> SELECT id1, id2, COUNT (*)
FROM test
GROUP BY id1, id2;

ID1 ID2 COUNT(*)
———- ———- ———-
۳ ۳ ۲۰۰۰
۲ ۲ ۱۰۰۰
۱ ۱ ۱

۳ rows selected.

توسط کاربری sys پارامتر CURSOR_SHARING برابر مقدار EXACT مقداردهی می‌شود.

SQL> ALTER SYSTEM SET CURSOR_SHARING=’EXACT’;

سپس مقدار پارامتر CURSOR_SHARING بررسی و SHARED_POOL تخلیه می‌شود. نکته قابل‌توجه این است که تا انتهای این مقاله همه دستورات تخلیه SHARED_POOL از طریق کاربری sys انجام می‌شود.

SQL> SHOW PARAMETER CURSOR_SHARING;

NAME TYPE VALUE
———————————— ———– ——————————
CURSOR_SHARING string EXACT

SQL> ALTER SYSTEM FLUSH SHARED_POOL;

تخلیه SHARED_POOL باعث حذف Cursors پیشین می‌شود. حال سه دستور زیر برای ایجاد Cursor اجرا می‌شود.

SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 1;

COUNT(*)
———-
۱
۱ row selected.

SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 2;

COUNT(*)
———-
۱۰۰۰
۱ row selected.

SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 3;

COUNT(*)
———-
۲۰۰۰
۱ row selected.

اکنون با استفاده از دستور زیر Parent Cursors ایجادشده برای هر یک از دستورات بالا مشاهده می‌شود.

SQL> SET LINES 120;
SQL> COL sql_text FOR a50 WORD_WRAPPED;
SQL> SELECT SQL_TEXT,
SQL_ID,
VERSION_COUNT,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQLAREA
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;

SQL_TEXT SQL_ID VERSION_COUNT HASH_VALUE PLAN_HASH_VALUE
————————————————– ————- ————- ———- —————
select count(*) from test where id1=3 1n09m564gh0q3 1 2297955011 4192825871
select count(*) from test where id1=2 20nhaap8uxf7s 1 1370405112 3507950989
select count(*) from test where id1=1 bavqx2mw26wg0 1 4163072480 3507950989

به‌منظور دریافت اطلاعات تکمیلی می‌توان از * برای مشاهده کلیه ستون‌های جدول V$SQLAREA استفاده کرد. همان‌طور که ملاحظه می‌شود، برای هر یک از دستورات مرحله قبل یک Parent Cursor ایجاد شده است. درصورتی‌که هر Query دارای مقادیر متفاوتی در بخش شرط باشد، برای هر Query یک Record بازگردانده می‌شود.
هر یک از دستورات SQL_ID/HASH_VALUE متفاوتی دارند.
برای هر Parent Cursor یک Child Cursor وجود دارد.(مقدار Version_Count برابر ۱ می‌باشد.)
طرح اجرایی برای دستوراتی با ID برابر ۲ و ۳ یکسان است. (FULL TABLE SCAN و مقدار PLAN_HASH_VALUE یکسانی دارند.)
طرح اجرایی برای دستور ID برابر ۱ متفاوت خواهد بود. (به دلیل استفاده از Index)
ممکن است در برخی مواقع بنا به شرایط مختلف پایگاه‌داده، Optimizer طرح‌های اجرای دیگری را ایجاد نماید. برای مثال ممکن است برای دستورات اول و دوم از INDEX RANGE SCAN و برای دستور سوم از INDEX FAST FULL SCAN استفاده شود.

SQL> COL child_number FOR 99;
SQL> SELECT SQL_TEXT,
SQL_ID,
CHILD_NUMBER CHILD#,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQL
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;

SQL_TEXT SQL_ID CHILD# HASH_VALUE PLAN_HASH_VALUE
————————————————– ————- ———- ———- —————
select count(*) from test where id1=3 1n09m564gh0q3 0 2297955011 4192825871
select count(*) from test where id1=2 20nhaap8uxf7s 0 1370405112 3507950989
select count(*) from test where id1=1 bavqx2mw26wg0 0 4163072480 3507950989

با استفاده از این دستور می‌توان تعداد Child Cursors را نیز مشاهده کرد. درمجموع تعداد ۶ Cursor متشکل از ۳ Parent Cursor و ۳ Child Cursor به وجود آمده است. هر یک از Cursors فضایی را در حافظه در اختیار دارند. Parent Cursors از این فضا برای نگهداری SQL Text ، و Child Cursors برای نگهداری طرح اجرایی، اطلاعات آماری اجرایی و اطلاعات محیط اجرایی استفاده می‌کنند.
اگر بجای Literals در قسمت شرط دستور از Bind Variable استفاده شود، تنها یک Parent Cursor برای هر سه دستور ایجاد می‌شود. سپس برای هر یک مقادیر یک Child Cursor ایجاد می‌شود.
SIMILAR
درصورتی‌که پارامتر CURSOR_SHARING برابر SIMILAR مقداردهی شود، Bind Variable را جایگزین Literals در قسمت شرط دستورات SQL می‌کند. بدین ترتیب یک Parent Cursor ایجاد کرده و برای مقادیر مختلف Child Cursor ایجاد می‌نماید.

Data Skew
پیش از ادامه بحث لازم است Data Skew تشریح گردد. میانگین داده‌ها از مجموع داده‌ها تقسیم بر تعداد داده‌ها به دست می‌آید. همچنین نما برابر است با داده‌ای که بیشترین تکرار را دارد. میانه را صرفاً برای داده‌هایی می‌توان محاسبه کرد که بتوان از بزرگ به کوچک مرتب کرد. پس از مرتب‌سازی داده از بزرگ به کوچک، داده‌ای که در میانه داده‌ها قرار می‌گیرد، میانه نامیده می‌شود. میانه داده‌ای است که نیمی از داده‌ها بزرگ‌تر از آن و نیمی از داده‌ها کوچک‌تر از آن می‌باشند. همچنین برای دسته‌بندی داده‌ها از بازه‌ها استفاده می‌شود.
اگر میانگین و میانه یکی باشند توزیع مقادیر کاملاً متقارن خواهد بود
اگر میانگین بزرگ‌تر از میانه باشد توزیع مقادیر دارای چولگی مثبت ( به طرف راست) است.
اگر میانگین کوچک‌تر از میانه باشد توزیع مقادیر دارای چولگی منفی ( به طرف چپ) است

اگر بر روی یک ستون از یک جدول Histogram تعریف بشود و همه داده‌ها در یک بازه قرار گیرند، Optimizer متوجه چولگی داده‌ها نمی‌شود و تنها یک Child Cursor برای هر سه دستور ایجاد می‌شود. اگر در این شرایط داده‌ها درون چند بازه قرار گیرند، Optimizer چولگی داده‌ها را متوجه شده و برای هر یک از دستورات یک Child Cursor ایجاد می‌کند؛ حتی اگر طرح‌های اجرایی یکسان باشند.
درصورتی‌که Histogram بر روی ستون id1 ایجاد نشده باشد و یا داده‌ها دارای چولگی نباشند، تنها یک Child Cursor ایجاد خواهد شد. مقدار SIMILAR برای پارامتر CURSOR_SHARING ، کاهش تعداد Parent Cursors را به همراه خواهد داشت.

CURSOR_SHARING=SIMILAR WITHOUT HISTOGRAM
حال به بررسی مقدار SIMILAR برای متغیر CURSOR_SHARING بدون ایجاد Histogram پرداخته می‌شود. ابتدا بر روی ستون id1 یک Histogram با Bucket برابر یک ایجاد می‌شود.

SQL> exec dbms_stats.gather_table_stats(OWNNAME => ‘HR’,-TABNAME => ‘TEST’,-ESTIMATE_PERCENT =>null,-METHOD_OPT => ‘FOR COLUMNS SIZE 1 ID1′);

artarad_cursor_1

شکل ۱ وضعیت جدول آزمایش در حالت کلی
پارامتر CURSOR_SHARING برابر مقدار SIMILAR مقداردهی می‌شود.

SQL> ALTER SYSTEM SET CURSOR_SHARING=’SIMILAR’;

سپس مقدار پارامتر CURSOR_SHARING بررسی و SHARED_POOL تخلیه می‌شود.

SQL> SHOW PARAMETER CURSOR_SHARING;

NAME TYPE VALUE
———————————— ———– ——————————
CURSOR_SHARING string SIMILAR
SQL> ALTER SYSTEM FLUSH SHARED_POOL;

اکنون دستورات SQL اجرا می‌شود.

SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 1;

COUNT(*)
———-
۱
۱ row selected.

SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 2;

COUNT(*)
———-
۱۰۰۰
۱ row selected.

SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 3;

COUNT(*)
———-
۲۰۰۰
row selected1.

حال با استفاده از دستور زیر Parent Cursors ایجادشده برای دستورات بالا مشاهده می‌شود. همان‌طور که مشاهده می‌شود، مقدار Literal حذف و بجای آن از Bind Variable استفاده شده است.

SQL> SELECT SQL_TEXT,
SQL_ID,
VERSION_COUNT,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQLAREA
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;

SQL_TEXT SQL_ID VERSION_COUNT HASH_VALUE PLAN_HASH_VALUE
————————————————– ————- ————- ———- —————
select count(*) from test where dzu7d3xymqrq3 1 2101042883 3507950989
id1=:”SYS_B_0″

همچنین برای این Parent Cursor تنها یک Child Cursor ایجاد شده است.

SQL> SELECT SQL_TEXT,
SQL_ID,
CHILD_NUMBER CHILD#,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQL
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;

SQL_TEXT SQL_ID CHILD# HASH_VALUE PLAN_HASH_VALUE
————————————————– ————- ———- ———- —————
select count(*) from test where dzu7d3xymqrq3 0 2101042883 3507950989
id1=:”SYS_B_0″

CURSOR_SHARING=SIMILAR WITH HISTOGRAM
ابتدا بر روی ستون id2 در ۴ بازه Histogram ساخته می‌شود.

SQL> exec dbms_stats.gather_table_stats(OWNNAME => ‘HR’,-
TABNAME => ‘TEST’,-
ESTIMATE_PERCENT =>null,-
CASCADE => TRUE,-
METHOD_OPT => ‘FOR COLUMNS SIZE 4 ID2’);

PL/SQL procedure successfully completed.

در تصویر زیر می‌توان Histogram ایجادشده را مشاهده نمود.

artarad_cursor_2

شکل ۲ وضعیت جدول آزمایش پس از ساخت Histogram
سپس SHARED_POOL تخلیه می‌شود.

SQL> ALTER SYSTEM FLUSH SHARED_POOL;
اکنون دستورات SQL اجرا می‌شود.

SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 1;
COUNT(*)
———-
۱
۱ row selected.
SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 2;
COUNT(*)
———-
۱۰۰۰
۱ row selected.
SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 3;
COUNT(*)
———-
۲۰۰۰
row selected1.

Parent Cursor و سه Child Cursor ایجادشده در خروجی دستور زیر مشاهده می‌شود.

SQL> COL sql_text FOR a30 WORD_WRAPPED
SQL> SELECT SQL_TEXT,
SQL_ID,
VERSION_COUNT,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQLAREA
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;
SQL_TEXT SQL_ID VERSION_COUNT HASH_VALUE PLAN_HASH_VALUE
—————————— ————- ————- ———- —————
select count(*) from test 07tpk6bm7j4qm 3 3866661587 3507950989
where id1=:”SYS_B_0″
SQL> SELECT SQL_TEXT,
SQL_ID,
CHILD_NUMBER CHILD#,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQL
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;
SQL_TEXT SQL_ID CHILD# HASH_VALUE PLAN_HASH_VALUE
—————————— ————- ———- ———- —————
select count(*) from test 3tcujqmqnqs8t 0 3981140249 2432738936
where id2=:”SYS_B_0″

select count(*) from test 3tcujqmqnqs8t 1 3981140249 1489241381
where id2=:”SYS_B_0″
select count(*) from test 3tcujqmqnqs8t 2 3981140249 2432738936
where id2=:”SYS_B_0″

درصورتی‌که Optimizer از چولگی داده‌ها مطلع باشد، برای هر مقدار از Literals یک Child Cursor ایجاد می‌کند و درصورتی‌که از چولگی داده‌ها باخبر نباشد، به ازای همه مقادیر یک Child Cursor در نظر می‌گیرد. بهترین حالت زمانی است که برای کلیه مقادیری که دارای طرح اجرایی یکسانی هستند، تنها یک Child Cursor ایجاد شود.
FORCE
وضعیت‌های Optimizer در زمانی که متغیر CURSOR_SHARING برابر FORCE باشد، به ۳ حالت تقسیم‌بندی می‌شود.
CURSOR_SHARING=FORCE In 11G Without Histogram
حالت نخست زمانی است که بر روی پایگاه‌داده نسخه ۱۱G بدون ایجاد Histogram متغیر CURSOR_SHARING برابر FORCE مقداردهی شود.
ابتدا پارامتر CURSOR_SHARING مقداردهی شده و سپس SHARED_POOL تخلیه می‌شود.

SQL> ALTER SYSTEM SET CURSOR_SHARING=’FORCE’;
SQL> SHOW PARAMETER CURSOR_SHARING
NAME TYPE VALUE
———————————— ———– ——————————
CURSOR_SHARING string FORCE
SQL> ALTER SYSTEM FLUSH SHARED_POOL;

سپس دستورات (شرط بر روی ستونی که دارای Histogram نیست) بر روی آن اجرا می‌شود.

SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 1;
COUNT(*)
———-
۱
۱ row selected.
SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 2;
COUNT(*)
———-
۱۰۰۰
۱ row selected.
SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 3;
COUNT(*)
———-
۲۰۰۰
row selected1.

وضعیت Parent Cursors بررسی می‌شود.

SQL> COL sql_text FOR a30 WORD_WRAPPED
SQL> SELECT SQL_TEXT,
SQL_ID,
VERSION_COUNT,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQLAREA
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;
SQL_TEXT SQL_ID VERSION_COUNT HASH_VALUE PLAN_HASH_VALUE
—————————— ————- ————- ———- —————
select count(*) from test 07tpk6bm7j4qm 3 3866661587 3507950989
where id1=:”SYS_B_0″

در این حالت یک Child Cursor ایجاد می‌شود.

SQL> COL child_number FOR 99;
SQL> SELECT SQL_TEXT,
SQL_ID,
CHILD_NUMBER CHILD#,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQL
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;
SQL_TEXT SQL_ID CHILD# HASH_VALUE PLAN_HASH_VALUE
—————————— ————- ———- ———- —————
select count(*) from test 07tpk6bm7j4qm 0 3866661587 3507950989
where id1=:”SYS_B_0″

CURSOR_SHARING=FORCE In 11G With Histogram
در حالت دوم مفروض است که Histogram از پیش ایجاد شده است. بنابراین ابتدا پارامتر SHARED_POOL تخلیه می‌شود.
سپس دستورات (شرط بر روی ستونی که دارای Histogram نیست) بر روی آن اجرا می‌شود.

SQL> SHOW PARAMETER CURSOR_SHARING;
NAME TYPE VALUE
———————————— ———– ——————————
CURSOR_SHARING string FORCE
SQL> ALTER SYSTEM FLUSH SHARED_POOL;

SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 1;
COUNT(*)
———-
۱
۱ row selected.
SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 2;
COUNT(*)
———-
۱۰۰۰
۱ row selected.
SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 3;
COUNT(*)
———-
۲۰۰۰
row selected1.

وضعیت Parent Cursors بررسی می‌شود.

SQL> COL sql_text FOR a30 WORD_WRAPPED
SQL> SELECT SQL_TEXT,
SQL_ID,
VERSION_COUNT,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQLAREA
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;
SQL_TEXT SQL_ID VERSION_COUNT HASH_VALUE PLAN_HASH_VALUE
—————————— ————- ————- ———- —————
select count(*) from test 3tcujqmqnqs8t 2 3981140249 2432738936
where id2=:”SYS_B_0″

در این حالت دو Child Cursor ایجاد شده است که هر یک دارای طرح اجرایی مجزایی می‌باشند.

SQL> COL child_number FOR 99
SQL> SELECT SQL_TEXT,
SQL_ID,
CHILD_NUMBER CHILD#,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQL
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;
SQL_TEXT SQL_ID CHILD# HASH_VALUE PLAN_HASH_VALUE
—————————— ————- ———- ———- —————
select count(*) from test 3tcujqmqnqs8t 0 3981140249 2432738936
where id2=:”SYS_B_0″
select count(*) from test 3tcujqmqnqs8t 1 3981140249 1489241381
where id2=:”SYS_B_0″

همان‌طور که مشاهده شد، درصورتی‌که مقدار پارامتر CURSOR_SHARING برابر FORCE باشد و طرح‌های اجرایی یکی باشند، از یک Child Cursor برای مقادیر مختلف استفاده می‌شود. این ویژگی که در نگارش ۱۱g ارائه شده است Adaptive Cursor Sharing نام دارد. بدین ترتیب میزان استفاده حافظه در بخش Shared Pool و Library Cache بهینه‌تر خواهد می‌شود.
CURSOR_SHARING=FORCE In 10G With/Witout Histogram
درصورتی‌که پایگاه‌داده اوراکل نگارش ۱۰g در دسترس نباشد، می‌توان Optimizer پایگاه‌داده نگارش ۱۱g را مجاب به طراحی به شیوه ۱۰g نمود. ابتدا با استفاده از دستور زیر Optimizer تنظیم می‌گردد.

SQL> ALTER SYSTEM SET optimizer_features_enable=’10.2.0.3′;
سپس Shared Pool تخلیه می‌شود.
SQL> ALTER SYSTEM FLUSH SHARED_POOL;
دستورات SQL اجرا می‌شود.
SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 1;
COUNT(*)
———-
۱
۱ row selected.
SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 2;
COUNT(*)
———-
۱۰۰۰
۱ row selected.
SQL> SELECT COUNT (*)
FROM test
WHERE id1 = 3;
COUNT(*)
———-
۲۰۰۰
row selected1.

وضعیت Parent Cursors بررسی می‌شود.

SQL> COL sql_text FOR a30 WORD_WRAPPED
SQL> SELECT SQL_TEXT,
SQL_ID,
VERSION_COUNT,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQLAREA
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;

SQL_TEXT SQL_ID VERSION_COUNT HASH_VALUE PLAN_HASH_VALUE
—————————— ————- ————- ———- —————
select count(*) from test 3tcujqmqnqs8t 1 3981140249 2432738936
where id2=:”SYS_B_0″

در این حالت دو Child Cursor ایجاد شده است که هر یک دارای طرح اجرایی مجزایی می‌باشند.

SQL> COL child_number FOR 99
SQL> SELECT SQL_TEXT,
SQL_ID,
CHILD_NUMBER CHILD#,
HASH_VALUE,
PLAN_HASH_VALUE
FROM V$SQL
WHERE LOWER (SQL_TEXT) LIKE ‘select count(*) from test%’
AND LOWER (SQL_TEXT) NOT LIKE ‘%HASH%’;

SQL_TEXT SQL_ID CHILD# HASH_VALUE PLAN_HASH_VALUE

—————————— ————- ———- ———- —————

select count(*) from test 3tcujqmqnqs8t 0 3981140249 2432738936

where id2=:”SYS_B_0″

نتیجه‌گیری
CURSOR_SHARING=EXACT
بیشترین میزان مصرف حافظه ( در بخش Library Cache ) در این حالت رخ می‌دهد. به ازای هر یک از مقادیر تخصیص داده‌شده به Bind Variable یک Parent Cursor و یک Child Cursor ایجاد می‌کند. همچنین بهترین حالت کارایی سیستم نیز در همین حالت رخ می‌دهد. برای هر یک از مقادیر به طرح اجرایی مجزا ایجاد خواهد شد.
CURSOR_SHARING=SIMILAR
در این حالت میزان مصرف حافظه ( در بخش Library Cache ) کاهش می‌یابد؛ زیرا تنها یک Parent Cursor ایجاد می‌شود. درصورتی‌که داده‌ها دارای چولگی نباشند و یا Optimizer از چولگی داده‌ها آگاه نباشد، بر اساس اولین مقدار Bind Variable طرح اجرایی ایجاد کرده و برای تمامی مقادیر استفاده می‌کند. در این حالت تنها یک Child Cursor ایجاد شده و کمترین میزان حافظه مصرف می‌شود. در این حالت کارایی سیستم در صورت وجود چولگی در داده‌ها با کاهش همراه خواهد بود.
درصورتی‌که Optimizer از چولگی داده آگاه باشد، Child Cursors متعددی ایجاد خواهد شد. برای هر یک از Child Cursors یک طرح اجرایی ایجاد می‌شود. بدین ترتیب کارایی سیستم در بهترین حالت قرار می‌گیرد؛ اما ممکن است برای تعدادی از Child Cursors طرح اجرایی یکسانی ایجاد شود.
CURSOR_SHARING=FORCE In 10g
در این وضعیت کمترین میزان حافظه مصرف می‌شود. تنها یک Parent Cursor و یک Child Cursor ایجاد می‌شود. درصورتی‌که داده‌ها دارای چولگی باشند، کارایی سیستم کاهش می‌یابد.
CURSOR_SHARING=FORCE In 11g (Adaptive Cursor Sharing)
در این حالت به دلیل ایجاد تنها یک Parent Cursor و یک Child Cursor میزان مصرف حافظه کاهش می‌یابد. درصورتی‌که داده‌ها دارای چولگی نباشند و یا Optimizer از چولگی داده‌ها آگاه نباشد، بر اساس اولین مقدار Bind Variable طرح اجرایی ایجاد کرده و برای تمامی مقادیر استفاده می‌کند. در این حالت تنها یک Child Cursor ایجاد شده و کمترین میزان حافظه مصرف می‌شود. این بخش شبیه حالت CURSOR_SHARING=SIMILAR می‌باشد.
درصورتی‌که داده‌ها دارای چولگی باشند و Optimizer نیز از آن آگاه باشد؛ به ازای هر یک از مقادیر یک Child Cursor ایجاد می‌کند (یک Child Cursor برای هر طرح اجرایی). در این حالت کارایی سیستم نیز در حالت بهترین وضعیت است؛ زیرا به ازای هر مقدار یک طرح اجرایی وجود دارد. در این حالت برخلاف حالت CURSOR_SHARING=SIMILAR طرح‌های اجرایی یکسانی برای Child Cursors مختلف ایجاد نشده و میزان مصرف حافظه نیز در حالت بهینه می‌باشد.

0 پاسخ

دیدگاه خود را ثبت کنید

تمایل دارید در گفتگوها شرکت کنید؟
در گفتگو ها شرکت کنید.

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

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