成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

數據庫性能問題總結--屢次發生的Oracle謂詞越界

數據庫 Oracle
近期在客戶現場屢次遇到由于統計信息過舊,導致執行計劃選錯引發的數據庫性能問題,今天做個總結。

 [[392208]]

本文轉載自微信公眾號「數據和云」,作者任艷杰。轉載本文請聯系數據和云公眾號。  

近期在客戶現場屢次遇到由于統計信息過舊,導致執行計劃選錯引發的數據庫性能問題,今天做個總結。

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

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

測試驗證

下面做一組測試,從執行計劃 cost 看謂詞越界的發生過程,先插入部分數據:

  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 

不收集統計信息,此時統計列統計信息過舊,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 

查詢結果返回 2081 行結果集。

  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. 計算結果為: 
  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 

查看結果集發現 dictionary 值為 1,這明顯是一個錯誤的執行計劃,由于統計信息過舊,已經低于謂詞條件區間(謂詞過界)導致 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 

重新收集統計信息再次查看執行計劃。

  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 

此時統計信息 HIGH_VALUE 已經和最初計算的值相等,Typ=2 Len=2: c3,b。再次查看執行計劃,此時 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 |   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 

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

預防方式

可對關鍵表實行按謂詞查詢條件分區,即按天或者按月分區可規避此問題發生。

責任編輯:武曉燕 來源: 數據和云
相關推薦

2023-11-16 17:12:33

數據庫oracle

2010-05-04 17:08:24

Oracle數據庫

2010-06-17 12:59:07

Oracle

2010-04-20 10:41:49

Oracle數據庫

2010-04-13 10:32:40

Oracle數據庫編程

2011-05-20 10:30:20

ORACLE數據庫性能優化

2011-05-18 09:39:19

Oracle數據庫性能優化

2011-04-12 10:09:33

Oracle數據庫關閉

2011-03-28 15:44:45

惠普數據庫Oracle數據庫

2009-02-01 13:33:13

Oracle數據庫配置

2010-11-15 16:13:24

Oracle數據庫性能

2010-05-07 17:39:02

Oracle數據庫性能

2010-05-10 15:50:39

Oracle數據庫性能

2011-09-02 10:06:51

OracleSqlLoad常用技巧

2010-04-07 09:31:02

Oracle數據庫

2010-04-09 15:08:17

Oracle 數據庫性

2011-06-14 15:11:59

ORACLE

2010-12-10 10:17:21

關系型數據庫

2010-04-12 16:43:59

Oracle數據庫

2011-03-17 14:09:25

Oracle數據庫字符
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 色噜噜狠狠色综合中国 | 免费观看黄色一级片 | 日韩中文一区二区三区 | av在线免费观看网址 | 日韩精品一区在线 | 午夜精品久久久久久久久久久久 | 日本aa毛片a级毛片免费观看 | 欧美一区二区三区视频 | 中文字幕伊人 | 亚洲瑟瑟 | 美美女高清毛片视频免费观看 | 国产精品一二区 | 在线观看国产视频 | 国产日产精品一区二区三区四区 | 国产激情视频在线 | 久久中文视频 | 久久久精品国产 | 日韩欧美在线视频播放 | 国产精品国产三级国产aⅴ中文 | 羞羞视频在线观免费观看 | 欧美6一10sex性hd | 日韩av黄色 | 免费网站国产 | 日韩一区二区在线视频 | 久久婷婷国产麻豆91 | 人人艹人人 | 欧美久久一区二区三区 | 午夜一级做a爰片久久毛片 精品综合 | 欧美一区二区三区四区五区无卡码 | 精品一区二区三区在线视频 | 在线免费观看黄网 | 亚洲精品自拍视频 | 91久久国产综合久久 | 天天做日日做 | 亚洲成人精品在线观看 | 性色av一区二区三区 | a在线视频 | 成人在线中文字幕 | 一区二区三区回区在观看免费视频 | 中文字幕av高清 | 亚洲精品黄 |