亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Oracle函數使索引列失效怎么辦

發布時間:2021-12-18 11:06:04 來源:億速云 閱讀:138 作者:小新 欄目:開發技術

小編給大家分享一下Oracle函數使索引列失效怎么辦,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

一、數據版本與原始語句及相關信息

1.版本信息

SQL> select * from v$version;                                       
                                                                    
BANNER                                                              
----------------------------------------------------------------    
Oracle Database 10g Release 10.2.0.3.0 - 64bit Production           
PL/SQL Release 10.2.0.3.0 - Production                              
CORE    10.2.0.3.0      Production                                  
TNS for Linux: Version 10.2.0.3.0 - Production                      
NLSRTL Version 10.2.0.3.0 - Production

 2.原始語句與其執行計劃

SQL> set autotrace traceonly exp;                                                                 
                                                                                                  
SELECT acc_num,                                                                                   
	   curr_cd,                                                                                     
	   DECODE('20110728',                                                                           
			  (SELECT TO_CHAR(LAST_DAY(TO_DATE('20110728', 'YYYYMMDD')),                                
							  'YYYYMMDD')                                                                       
			   FROM   DUAL),                                                                            
			  0,                                                                                        
			  adj_credit_int_lv1_amt + adj_credit_int_lv2_amt -                                         
			  adj_debit_int_lv1_amt - adj_debit_int_lv2_amt) AS interest                                
FROM   acc_pos_int_tbl ACC_POS_INT_TBL1                                                           
WHERE  SUBSTR(business_date, 1, 6) = SUBSTR('20110728', 1, 6)                                     
	   AND business_date <= '20110728';                                                             
                                                                                                  
Execution Plan                                                                                    
----------------------------------------------------------                                        
Plan hash value: 3114115399                                                                       
                                                                                                  
-------------------------------------------------------------------------------------             
| Id  | Operation         | Name            | Rows  | Bytes | Cost (%CPU)| Time     |             
-------------------------------------------------------------------------------------             
|   0 | SELECT STATEMENT  |                 |   336K|    12M| 96399   (1)| 00:19:17 |             
|   1 |  FAST DUAL        |                 |     1 |       |     2   (0)| 00:00:01 |             
|*  2 |  TABLE ACCESS FULL| ACC_POS_INT_TBL |   336K|    12M| 96399   (1)| 00:19:17 |             
-------------------------------------------------------------------------------------             
                                                                                                  
Predicate Information (identified by operation id):                                               
---------------------------------------------------                                               
                                                                                                  
   2 - filter(SUBSTR("BUSINESS_DATE",1,6)='201107' AND                                            
              "BUSINESS_DATE"<='20110728')

3.表上的索引信息

SQL> set autotrace off;                                                                                  
SQL> set linesize 190                                                                                    
SQL> @Idx_Info                                                                                           
Enter value for owner: goex_admin                                                                        
old  10:           AND owner = upper('&owner')                                                           
new  10:           AND owner = upper('goex_admin')                                                       
Enter value for table_name: ACC_POS_INT_TBL                                                              
old  11:           AND a.table_name = upper('&table_name')                                               
new  11:           AND a.table_name = upper('ACC_POS_INT_TBL')                                           
                                                                                                         
TABLE_NAME         INDEX_NAME               COL_NAM              CL_POS STATUS   IDX_TYP         DSCD    
------------------ ------------------------ -------------------- ------ -------- --------------- ----    
ACC_POS_INT_TBL    ACC_POS_INT_10DIG_IDX    SYS_NC00032$              1 VALID    FUNCTION-BASED  ASC     
                                                                                 NORMAL                  
                                                                                                         
ACC_POS_INT_TBL    ACC_POS_INT_10DIG_IDX    BUSINESS_DATE             2 VALID    FUNCTION-BASED  ASC     
                                                                                 NORMAL                  
                                                                                                         
ACC_POS_INT_TBL    ACC_POS_INT_10DIG_IDX    CURR_CD                   3 VALID    FUNCTION-BASED  ASC     
                                                                                 NORMAL                  
                                                                                                         
ACC_POS_INT_TBL    PK_ACC_POS_INT_TBL       ACC_NUM                   1 VALID    NORMAL          ASC     
ACC_POS_INT_TBL    PK_ACC_POS_INT_TBL       BUSINESS_DATE             2 VALID    NORMAL          ASC

從索引的情況上來看有一個基于主鍵的索引包含了BUSINESS_DATE列,而查詢語句并沒有走索引而是選擇的全表掃描,而且預估所返回的行Rows與bytes也是大的驚人,cost的值96399,接近10W。

二、分析與改造SQL語句

1.原始的SQL語句分析

SQL語句中where子句的business_date列實現對記錄過濾business_date <= '20110728'條件不會限制索引的使用SUBSTR(business_date, 1, 6) = SUBSTR('20110728', 1, 6)使用了SUBSTR函數,限制了優化器選擇索引基于business_date列來建立索引函數,從已存在的索引來看,必要性不大

2.改造SQL語句

SUBSTR(business_date, 1, 6) = SUBSTR('20110728', 1, 6)的實質是等于當月,即限制返回的行為從2011.7.1日至2011.7.28因此其返回的記錄大于等于2011.7.1,且小于2011.7.28做如下改造business_date >=to_char(last_day(add_months(to_date('20110728','yyyymmdd'),-1)) + 1,'yyyymmdd')

3.改造后的SQL語句

SELECT acc_num,                                                                
	   curr_cd,                                                                  
	   DECODE('20110728',                                                        
			  (SELECT TO_CHAR(LAST_DAY(TO_DATE('20110728', 'YYYYMMDD')),             
							  'YYYYMMDD')                                                    
			   FROM   DUAL),                                                         
			  0,                                                                     
			  adj_credit_int_lv1_amt + adj_credit_int_lv2_amt -                      
			  adj_debit_int_lv1_amt - adj_debit_int_lv2_amt) AS interest             
FROM   acc_pos_int_tbl ACC_POS_INT_TBL1                                        
WHERE  business_date >=                                                        
	   to_char(last_day(add_months(to_date('20110728', 'yyyymmdd'), -1)) + 1,    
			   'yyyymmdd')                                                           
	   AND business_date <= '20110728';

4.改造后的執行計劃

Execution Plan                                                                                               
----------------------------------------------------------                                                   
Plan hash value: 66267922                                                                                    
                                                                                                             
--------------------------------------------------------------------------------------------------           
| Id  | Operation                   | Name               | Rows  | Bytes | Cost (%CPU)| Time     |           
--------------------------------------------------------------------------------------------------           
|   0 | SELECT STATEMENT            |                    |  1065K|    39M| 75043   (1)| 00:15:01 |           
|   1 |  FAST DUAL                  |                    |     1 |       |     2   (0)| 00:00:01 |           
|   2 |  TABLE ACCESS BY INDEX ROWID| ACC_POS_INT_TBL    |  1065K|    39M| 75043   (1)| 00:15:01 |           
|*  3 |   INDEX SKIP SCAN           | PK_ACC_POS_INT_TBL | 33730 |       | 41180   (1)| 00:08:15 |           
--------------------------------------------------------------------------------------------------           
                                                                                                             
Predicate Information (identified by operation id):                                                          
---------------------------------------------------                                                          
                                                                                                             
   3 - access("BUSINESS_DATE">='20110701' AND "BUSINESS_DATE"<='20110728')                                   
       filter("BUSINESS_DATE">='20110701' AND "BUSINESS_DATE"<='20110728')

改造后可以看到SQL語句的執行計劃已經由原來的全表掃描改為執行INDEX SKIP SCAN,但其cost也并沒有降低多少

三、進一步分析

1.表的相關信息

SQL> @Tab_Stat                                                                                        
Enter value for input_table_name: ACC_POS_INT_TBL                                                     
old  11: WHERE  table_name = upper('&input_table_name')                                               
new  11: WHERE  table_name = upper('ACC_POS_INT_TBL')                                                 
Enter value for input_owner: goex_admin                                                               
old  12:           AND owner = upper('&input_owner')                                                  
new  12:           AND owner = upper('goex_admin')                                                    
                                                                                                      
  NUM_ROWS       BLKS    EM_BLKS  AVG_SPACE  CHAIN_CNT AVG_ROW_LEN AVG_ROWS_PER_BLOCK LST_ANLY  STA   
---------- ---------- ---------- ---------- ---------- ----------- ------------------ --------- ---   
  33659947     437206       1322        855          0          99                 77 27-SEP-11 NO

2.索引的相關信息

SQL> @Idx_Stat                                                                                                       
Enter value for input_table_name: ACC_POS_INT_TBL                                                                    
old  11: WHERE  table_name = upper('&input_table_name')                                                              
new  11: WHERE  table_name = upper('ACC_POS_INT_TBL')                                                                
Enter value for input_owner: goex_admin                                                                              
old  12:           AND owner = upper('&input_owner')                                                                 
new  12:           AND owner = upper('goex_admin')                                                                   
                                                                                                                     
BLEV IDX_NAME                          LF_BLKS   DST_KEYS   NUM_ROWS LF_PER_KEY DAT_BLK_PER_KEY   CLUS_FCT LST_ANLY  
---- ------------------------------ ---------- ---------- ---------- ---------- --------------- ---------- --------- 
   3 PK_ACC_POS_INT_TBL                 155658   33777720   33777720          1               1   33777447 27-SEP-11 
   3 ACC_POS_INT_10DIG_IDX              160247   32850596   32850596          1               1   32763921 27-SEP-11

3.嘗試在BUSINESS_DATE列上創建索引

SQL> create index I_ACC_POS_INT_TBL_BS_DT on ACC_POS_INT_TBL(BUSINESS_DATE) tablespace tbs_tmp nologging;             
                                                                                                                      
Index created.                                                                                                        
                                                                                                                      
SQL> @Idx_Stat                                                                                                        
Enter value for input_table_name: ACC_POS_INT_TBL                                                                     
old  11: WHERE  table_name = upper('&input_table_name')                                                               
new  11: WHERE  table_name = upper('ACC_POS_INT_TBL')                                                                 
Enter value for input_owner: goex_admin                                                                               
old  12:           AND owner = upper('&input_owner')                                                                  
new  12:           AND owner = upper('goex_admin')                                                                    
                                                                                                                      
BLEV IDX_NAME                          LF_BLKS   DST_KEYS   NUM_ROWS LF_PER_KEY DAT_BLK_PER_KEY   CLUS_FCT LST_ANLY   
---- ------------------------------ ---------- ---------- ---------- ---------- --------------- ---------- ---------  
   2 I_ACC_POS_INT_TBL_BS_DT             93761        908   33659855        103             506     460007 30-SEP-11  
   3 PK_ACC_POS_INT_TBL                 155658   33777720   33777720          1               1   33777447 27-SEP-11  
   3 ACC_POS_INT_10DIG_IDX              160247   32850596   32850596          1               1   32763921 27-SEP-11

建立索引后聚簇因子較小,差不多接近表上塊的數量

4.使用新創建索引后的執行計劃

Execution Plan                                                                                               
----------------------------------------------------------                                                   
Plan hash value: 2183566226                                                                                  
                                                                                                             
-------------------------------------------------------------------------------------------------------      
| Id  | Operation                   | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |      
-------------------------------------------------------------------------------------------------------      
|   0 | SELECT STATEMENT            |                         |  1065K|    39M| 17586   (1)| 00:03:32 |      
|   1 |  FAST DUAL                  |                         |     1 |       |     2   (0)| 00:00:01 |      
|   2 |  TABLE ACCESS BY INDEX ROWID| ACC_POS_INT_TBL         |  1065K|    39M| 17586   (1)| 00:03:32 |      
|*  3 |   INDEX RANGE SCAN          | I_ACC_POS_INT_TBL_BS_DT |  1065K|       |  2984   (1)| 00:00:36 |      
-------------------------------------------------------------------------------------------------------      
                                                                                                             
Predicate Information (identified by operation id):                                                          
---------------------------------------------------                                                          
                                                                                                             
   3 - access("BUSINESS_DATE">='20110701' AND "BUSINESS_DATE"<='20110728')

從上面的執行計劃看出,SQL語句已經選擇了新建的索引盡管返回的rows,bytes沒有明顯的變化,但cost已經少了近7倍。

看完了這篇文章,相信你對“Oracle函數使索引列失效怎么辦”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

万州区| 且末县| 虹口区| 抚松县| 定安县| 富平县| 周宁县| 南开区| 沛县| 资溪县| 长顺县| 平乐县| 肇州县| 无棣县| 吴忠市| 积石山| 合山市| 巧家县| 永仁县| 博野县| 温州市| 安远县| 郯城县| 莆田市| 龙岩市| 威海市| 霍林郭勒市| 锡林浩特市| 香河县| 博客| 肥乡县| 泸州市| 德安县| 拜城县| 溆浦县| 阳曲县| 巫山县| 琼中| 渑池县| 澄城县| 侯马市|