Oracle中查询时候使index索引失效的限制条件
Oracle中查询时候使index索引失效的限制条件
<span style="color:#333333;">select * from ( select temp.*, rownum row_id from ( select CLEAR_MERCHID,MERCH_NAME,AMOUNT,decode(status,'0','待确认','1','完成','2','已冲正') as status ,RATE,FEE,BROKER_CHARGE,UNION_CHARGE,ACT_AMOUNT,RCV_AMOUNT ,RESP_CODE,VOUCHNO,CARDNO,TRAN_DATE,STLEXDAY,CLEAR_DATE,SETTLE_DATE_FN ,decode(TRAN_TYPE,'0','签到','1','信用卡还款','2','信用卡还款冲正','3','公共事业缴费','4','公共事业缴费冲正','5','手机话费充值','6','余额查询','7','公共事业账单查询' ,'8','上海公共事业缴费','9','消费','@','消费冲正','P','卡卡转账','E','北京账单查询','F','北京公共事业缴费','G','北京公共事业缴费冲正','W','四川公共支付账单查询','X','四川公共支付账单缴费',TRAN_TYPE) as TRAN_TYPE ,FLAGNAME,BROKERID ,IBOX_ID,REFNO,ERR_CODE,MCH_TYPE ,decode(CHANNL_ID,'2001','上海银商','2002','深圳银商','2003','易宝支付','2004', '银视通支付','2005','光大银行','2006','友邦多渠道(上海银联)' ,'2007','海科融通','2008','腾付通','2009','快钱支付','2010','浦发银行','2011','农业银行','2012','讯联支付','2013','宁波通商' ,'2014','卡富通支付','2015','联动优势','2016','上海轩辰','2017','支付宝收单','2018','微信支付','2019','翰鑫支付' ,CHANNL_ID) as CHANNL_ID ,SETTLEBATCH,ORDER_ID,TRAN_MERCHID,TRAN_TERMID,SRC_ID from vwsaledetail where 1=1 AND </span><span style="color:#cc66cc;">to_number(to_char(to_date(TRAN_DATE,'yyyy-mm-dd hh24:mi:ss'),'YYYYMMDD')) >= to_number(substr(?,0,8)) AND to_number(to_char(to_date(TRAN_DATE,'yyyy-mm-dd hh24:mi:ss'),'YYYYMMDD')) <= to_number(substr(?,0,8)) AND to_number(CLEAR_DATE) >= to_number(substr(?,0,8)) AND to_number(CLEAR_DATE) <= to_number(substr(?,0,8)</span><span style="color:#333333;">) order by tran_date desc ) temp where rownum <= 20) where row_id > 0 </span>
VIEW CLEAR_TEST 188776 20 9940
COUNT STOPKEY
VIEW CLEAR_TEST 188776 105 50820
SORT ORDER BY STOPKEY 188776 105 29820
NESTED LOOPS 188775 105 29820
NESTED LOOPS 188775 105 29820
TABLE ACCESS FULL CLEAR_TEST TRADEWASTE 188565 105 21630
INDEX UNIQUE SCAN CLEAR_TEST PK_BSTEAM 1 1
TABLE ACCESS BY INDEX ROWID CLEAR_TEST BSTEAM 2 1 78
WHERE 子句中使用函数 <span style="color:#ff0000;">如果没有使用基于函数的索引,那么 where 子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引</span>。例如: select * from staff where <span style="color:#ff6666;">trunc(birthdate)</span> = '01-MAY-82'; 但是把函数应用在条件上,索引是可以生效的,把上面的语句改成下面的语句,就可以通过索引进行查找。 select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);
select * from ( select temp.*, rownum row_id from ( select CLEAR_MERCHID,MERCH_NAME,AMOUNT,decode(status,'0','待确认','1','完成','2','已冲正') as status ,RATE,FEE,BROKER_CHARGE,UNION_CHARGE,ACT_AMOUNT,RCV_AMOUNT ,RESP_CODE,VOUCHNO,CARDNO,TRAN_DATE,STLEXDAY,CLEAR_DATE,SETTLE_DATE_FN ,decode(TRAN_TYPE,'0','签到','1','信用卡还款','2','信用卡还款冲正','3','公共事业缴费','4','公共事业缴费冲正','5','手机话费充值','6','余额查询','7','公共事业账单查询' ,'8','上海公共事业缴费','9','消费','@','消费冲正','P','卡卡转账','E','北京账单查询','F','北京公共事业缴费','G','北京公共事业缴费冲正','W','四川公共支付账单查询','X','四川公共支付账单缴费',TRAN_TYPE) as TRAN_TYPE ,FLAGNAME,BROKERID ,IBOX_ID,REFNO,ERR_CODE,MCH_TYPE ,decode(CHANNL_ID,'2001','上海银商','2002','深圳银商','2003','易宝支付','2004', '银视通支付','2005','光大银行','2006','友邦多渠道(上海银联)' ,'2007','海科融通','2008','腾付通','2009','快钱支付','2010','浦发银行','2011','农业银行','2012','讯联支付','2013','宁波通商' ,'2014','卡富通支付','2015','联动优势','2016','上海轩辰','2017','支付宝收单','2018','微信支付','2019','翰鑫支付' ,CHANNL_ID) as CHANNL_ID ,SETTLEBATCH,ORDER_ID,TRAN_MERCHID,TRAN_TERMID,SRC_ID from vwsaledetail WHERE <span style="color:#cc66cc;">TRAN_DATE >= ? AND TRAN_DATE <= ? AND CLEAR_DATE >= ? AND CLEAR_DATE <= ? order by tran_date desc</span> ) temp where rownum <= 40) where row_id > 20
VIEW CLEAR_TEST 8 1 497
COUNT STOPKEY
VIEW CLEAR_TEST 8 1 484
NESTED LOOPS 8 1 284
NESTED LOOPS 8 1 284
TABLE ACCESS BY INDEX ROWID CLEAR_TEST TRADEWASTE 6 1 206
INDEX RANGE SCAN DESCENDING CLEAR_TEST INDEX_TRAN_DATE 4 2
INDEX UNIQUE SCAN CLEAR_TEST PK_BSTEAM 1 1
TABLE ACCESS BY INDEX ROWID CLEAR_TEST BSTEAM 2 1 78
1. 没有 WHERE 子句 2. 使用 IS NULL 和 IS NOT NULL SELECT ... FROM emp WHERE comm IS NULL; comm 列的索引会失效 3. WHERE 子句中使用函数 如果没有使用基于函数的索引,那么 where 子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。例如: select * from staff where trunc(birthdate) = '01-MAY-82'; 但是把函数应用在条件上,索引是可以生效的,把上面的语句改成下面的语句,就可以通过索引进行查找。 select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999); 注意:对于 MIN, MAX 函数,Oracle 仍然使用索引。 4. 使用 LIKE ‘%T’ 进行模糊查询 5. WHERE 子句中使用不等于操作 不等于操作包括:<>, !=, NOT colum >= ?, NOT colum <= ? 对于这个限制条件可以通过 OR 替代,例如: colum <> 0 ===> colum>0 OR colum<0 6. 等于和范围索引不会被合并使用 SELECT emp_id, emp_m, salary_q ... FROM emp WHERE job='manager' AND deptno>10 job 和 deptno 都是非唯一索引,这种条件下 oracle 不会合并索引,它只会使用第一个索引。 7. 比较不匹配数据类型 dept_id是一个varchar2型的字段,在这个字段上有索引,但是下面的语句会执行全表扫描。 select * from dept where dept_id = 900198; 这是因为 oracle 会自动把 where 子句转换成 to_number(dept_id)=900198,相当于使用函数,这样就限制了索引的使用。正确写法如下: select * from dept where dept_id = '900198';
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。