自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

數(shù)據(jù)庫性能問題總結(jié)--屢次發(fā)生的Oracle謂詞越界

數(shù)據(jù)庫 Oracle
近期在客戶現(xiàn)場屢次遇到由于統(tǒng)計信息過舊,導致執(zhí)行計劃選錯引發(fā)的數(shù)據(jù)庫性能問題,今天做個總結(jié)。

 [[392208]]

本文轉(zhuǎn)載自微信公眾號「數(shù)據(jù)和云」,作者任艷杰。轉(zhuǎn)載本文請聯(lián)系數(shù)據(jù)和云公眾號。  

近期在客戶現(xiàn)場屢次遇到由于統(tǒng)計信息過舊,導致執(zhí)行計劃選錯引發(fā)的數(shù)據(jù)庫性能問題,今天做個總結(jié)。

謂詞越界常見發(fā)生在 where 謂詞是時間字段的情況,總的來說統(tǒng)計信息記錄的是一個過舊的時間,而 SQL 傳入的時間是一個最新的時間范圍(往往是 <time time1<c<time2)由于統(tǒng)計信息不全,按照 CBO 計算出來的結(jié)果集就很小,在多表關聯(lián)的情況下,CBO 就會選擇認為的最優(yōu)的關聯(lián)方式,而實際執(zhí)行時發(fā)現(xiàn)不是那么回事,有大量結(jié)果集需要掃描,就會爆發(fā) SQL 性能問題。

謂詞越界就是 select 的謂詞的條件不在統(tǒng)計信息 low_value 和 high_value 之間,在實際選擇結(jié)果集要大于 CBO 記錄的結(jié)果集數(shù)量,即實際的 selectivity 偏大,這種情況下 CBO 評估出來的 selectivity 會出現(xiàn)嚴重的偏差,導致 CBO 選錯執(zhí)行計劃。

測試驗證

下面做一組測試,從執(zhí)行計劃 cost 看謂詞越界的發(fā)生過程,先插入部分數(shù)據(jù):

  1. DECLARE 
  2. INT
  3. BEGIN 
  4. i := 78179; 
  5. WHILE(i < 100000) 
  6. LOOP 
  7. i := i + 1; 
  8. INSERT INTO test_obj(object_id) VALUES(i); 
  9. COMMIT
  10. END LOOP; 
  11. END

查看此時的 num_rows:

  1. TEST@PROD1> select count(*) from test_obj; 
  2.   COUNT(*) 
  3. ---------- 
  4.      94283 
  5. TEST@PROD1> select max(object_ID),dump(max(object_id),16) from test_obj; 
  6.   
  7. MAX(OBJECT_ID) DUMP(MAX(OBJECT_ID),16) 
  8. -------------- ---------------------------------------- 
  9.         100000 Typ=2 Len=2: c3,b     
  10. TEST@PROD1> select min(object_ID),dump(min(object_id),16) from test_obj; 
  11.   
  12. MIN(OBJECT_ID   )               DUMP(MIN(OBJECT_ID),16) 
  13. ------------------------------ ---------------------------------------- 
  14.       2                          Typ=2 Len=2: c1,3        --C103 

不收集統(tǒng)計信息,此時統(tǒng)計列統(tǒng)計信息過舊,HIGH_VALUE 依然是原來的值 78179。

  1. TEST@PROD1> select  low_value ,high_value,num_distinct,num_nulls from  DBA_TAB_COL_STATISTICS where table_name='TEST_OBJ' and owner='TEST'
  2.   
  3.                                                                   Distinct     Number 
  4. LOW_VALUE                      HIGH_VALUE                           Values      Nulls 
  5. ------------------------------ ------------------------------ ------------ ---------- 
  6. C103                           C3085250                             72,462(原值)  0 

查詢結(jié)果返回 2081 行結(jié)果集。

  1. TEST@PROD1> select count(*) from test_obj where object_id between 78200 and 81000; 
  2.   COUNT(*) 
  3. ---------- 
  4.       2801 
  5. 計算公式為: 
  6. selectivity=((VAL2 - VAL1) / (HIGH_VALUE - LOW_VALUE)+2 / NUM_DISTINCT) * null_adjust 
  7. null_adjust=(NUM_ROES - NUM_NULLS) / NUM_ROES 
  8.  
  9. 計算結(jié)果為: 
  10. TEST@PROD1>  select round(((81000-78200)/(100000-2)+2/94283)*(94283-0)/94283*94283) from dual;  
  11.   
  12. ROUND(((81000-78200)/(100000-2)+2/94283)*(94283-0)/94283*94283) 
  13. --------------------------------------------------------------- 
  14.                                                            2642 

查看結(jié)果集發(fā)現(xiàn) dictionary 值為 1,這明顯是一個錯誤的執(zhí)行計劃,由于統(tǒng)計信息過舊,已經(jīng)低于謂詞條件區(qū)間(謂詞過界)導致 CBO 低估了查詢成本。

  1. TEST@PROD1>  select count(*) from test_obj where object_id between 78200 and 81000; 
  2.   
  3. Execution Plan 
  4. ---------------------------------------------------------- 
  5. Plan hash value: 2217143630 
  6.   
  7. ------------------------------------------------------------------------------- 
  8. | Id  | Operation          | Name     | Rows  | Bytes | Cost (%CPU)| Time     | 
  9. ------------------------------------------------------------------------------- 
  10. |   0 | SELECT STATEMENT   |          |     1 |     5 |   289   (1)| 00:00:04 | 
  11. |   1 |  SORT AGGREGATE    |          |     1 |     5 |            |          | 
  12. |*  2 |   TABLE ACCESS FULL| TEST_OBJ |     1 |     5 |   289   (1)| 00:00:04 | 
  13. ------------------------------------------------------------------------------- 
  14.   
  15. Predicate Information (identified by operation id): 
  16. --------------------------------------------------- 
  17.   
  18.    2 - filter("OBJECT_ID">=78200 AND "OBJECT_ID"<=81000) 
  19.   
  20.   
  21. Statistics 
  22. ---------------------------------------------------------- 
  23.           1  recursive calls 
  24.           0  db block gets 
  25.        1117  consistent gets 
  26.           0  physical reads 
  27.           0  redo size 
  28.         423  bytes sent via SQL*Net to client 
  29.         419  bytes received via SQL*Net from client 
  30.           2  SQL*Net roundtrips to/from client 
  31.           0  sorts (memory) 
  32.           0  sorts (disk) 
  33.           1  rows processed 

重新收集統(tǒng)計信息再次查看執(zhí)行計劃。

  1. TEST@PROD1> exec dbms_stats.gather_table_stats('test','test_obj'); 
  2. TEST@PROD1> select  low_value ,high_value,num_distinct,num_nulls from  DBA_TAB_COL_STATISTICS where table_name='TEST_OBJ' and owner='TEST'
  3.   
  4.                                               Distinct     Number 
  5. LOW_VALUE            HIGH_VALUE                 Values      Nulls 
  6. -------------------- -------------------- ------------ ---------- 
  7. C103                 C30B                       94,283          0 

此時統(tǒng)計信息 HIGH_VALUE 已經(jīng)和最初計算的值相等,Typ=2 Len=2: c3,b。再次查看執(zhí)行計劃,此時 CBO 已經(jīng)能夠產(chǎn)生了正確的執(zhí)行計劃了。

執(zhí)行計劃為:

  1. TEST@PROD1> select count(*) from test_obj where object_id between 78200 and 81000; 
  2.   
  3. Execution Plan 
  4. ---------------------------------------------------------- 
  5. Plan hash value: 2217143630 
  6.   
  7. ------------------------------------------------------------------------------- 
  8. | Id  | Operation          | Name     | Rows  | Bytes | Cost (%CPU)| Time     | 
  9. ------------------------------------------------------------------------------- 
  10. |   0 | SELECT STATEMENT   |          |     1 |     5 |   314   (1)| 00:00:04 | 
  11. |   1 |  SORT AGGREGATE    |          |     1 |     5 |            |          | 
  12. |*  2 |   TABLE ACCESS FULL| TEST_OBJ |  2642 | 13210 |   314   (1)| 00:00:04 | 
  13. ------------------------------------------------------------------------------- 
  14.   
  15. Predicate Information (identified by operation id): 
  16. --------------------------------------------------- 
  17.   
  18.    2 - filter("OBJECT_ID">=78200 AND "OBJECT_ID"<=81000) 
  19.   
  20.   
  21. Statistics 
  22. ---------------------------------------------------------- 
  23.           0  recursive calls 
  24.           0  db block gets 
  25.        1117  consistent gets 
  26.           0  physical reads 
  27.           0  redo size 
  28.         423  bytes sent via SQL*Net to client 
  29.         419  bytes received via SQL*Net from client 
  30.           2  SQL*Net roundtrips to/from client 
  31.           0  sorts (memory) 
  32.           0  sorts (disk) 
  33.           1  rows processed 

謂詞越界主要發(fā)生在大表,按照 Oracle 統(tǒng)計信息收集機制,表的數(shù)據(jù)變化量達到 10% 以上才會進行統(tǒng)計信息收集,大表不常收集統(tǒng)計信息就容易爆發(fā)謂詞越界。

預防方式

可對關鍵表實行按謂詞查詢條件分區(qū),即按天或者按月分區(qū)可規(guī)避此問題發(fā)生。

責任編輯:武曉燕 來源: 數(shù)據(jù)和云
相關推薦

2010-05-04 17:08:24

Oracle數(shù)據(jù)庫

2023-11-16 17:12:33

數(shù)據(jù)庫oracle

2010-06-17 12:59:07

Oracle

2010-04-20 10:41:49

Oracle數(shù)據(jù)庫

2010-04-13 10:32:40

Oracle數(shù)據(jù)庫編程

2011-04-12 10:09:33

Oracle數(shù)據(jù)庫關閉

2011-05-20 10:30:20

ORACLE數(shù)據(jù)庫性能優(yōu)化

2011-05-18 09:39:19

Oracle數(shù)據(jù)庫性能優(yōu)化

2011-03-28 15:44:45

惠普數(shù)據(jù)庫Oracle數(shù)據(jù)庫

2011-09-02 10:06:51

OracleSqlLoad常用技巧

2010-05-10 15:50:39

Oracle數(shù)據(jù)庫性能

2009-02-01 13:33:13

Oracle數(shù)據(jù)庫配置

2010-11-15 16:13:24

Oracle數(shù)據(jù)庫性能

2010-05-07 17:39:02

Oracle數(shù)據(jù)庫性能

2011-06-14 15:11:59

ORACLE

2010-04-07 09:31:02

Oracle數(shù)據(jù)庫

2010-04-09 15:08:17

Oracle 數(shù)據(jù)庫性

2010-12-10 10:17:21

關系型數(shù)據(jù)庫

2011-03-17 14:09:25

Oracle數(shù)據(jù)庫字符

2010-04-12 16:43:59

Oracle數(shù)據(jù)庫
點贊
收藏

51CTO技術(shù)棧公眾號