查询语句如下(其中start_time,report_time,imsi为联合索引,索引类型为local):/* Formatted on 2011/10/24 17:07 (Formatter Plus v4.8.8) */ SELECT a.start_time, a.report_time, a.imsi, a.cdrid FROM cdr_data_a20111024 a WHERE EXISTS ( SELECT cdrid FROM cdr_data_a20111024 b WHERE (b.cdrid = a.cdrid OR b.base_cdrid = a.cdrid) AND ( (b.start_time BETWEEN TO_DATE ('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss' ) - 2 / 24 AND TO_DATE ('2011-10-24 23:57:47', 'yyyy-mm-dd hh24:mi:ss' ) ) AND (b.report_time > TO_DATE ('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss' ) ) ) AND ( b.imsi IN ('460022517717646') OR b.peer_number IN ('460022517717646') )) AND ( (a.start_time BETWEEN TO_DATE ('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss' ) - 2 / 24 AND TO_DATE ('2011-10-24 23:57:47', 'yyyy-mm-dd hh24:mi:ss' ) ) AND (a.report_time > TO_DATE ('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss') ) ) AND (a.imsi='460022517717646' OR a.peer_number ='460022517717646' )
统计信息 ---------------------------------------------------------- 1 recursive calls 0 db block gets 11163067 consistent gets 0 physical reads 1128 redo size 1163 bytes sent via SQL*Net to client 349 bytes received via SQL*Net from client 3 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 16 rows processed
试下改成With的方式呢 WITH w1 AS ( SELECT b.CDRID, b.BASE_CDRID, b.START_TIME, b.REPORT_TIME, b.IMSI FROM CDR_DATA_A20111024 B WHERE ((B.START_TIME BETWEEN TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss') - 2 / 24 AND TO_DATE('2011-10-24 23:57:47', 'yyyy-mm-dd hh24:mi:ss')) AND (B.REPORT_TIME > TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss'))) AND (B.IMSI IN ('460022517717646') OR B.PEER_NUMBER IN ('460022517717646'))) SELECT T1.START_TIME, T1.REPORT_TIME, T1.IMSI, T1.CDRID FROM W1 T1 WHERE EXISTS (SELECT T2.CDRID FROM W1 T2 WHERE T1. CDRID = T2.CDRID OR T1.BASE_CDRID = T2.BASE_CDRID)
你的sql需求是什么呢?表a的条件和表b的条件除了(b.cdrid = a.cdrid OR b.base_cdrid = a.cdrid)其他都一样的,因为表A和表B同一个表,(b.cdrid = a.cdrid OR b.base_cdrid = a.cdrid)在cdrid不为null的时候永远是true,所以你的sql等价:SELECT a.start_time, a.report_time, a.imsi, a.cdrid FROM cdr_data_a20111024 a WHERE ( (a.start_time BETWEEN TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss') - 2 / 24 AND TO_DATE('2011-10-24 23:57:47', 'yyyy-mm-dd hh24:mi:ss')) AND (a.report_time > TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss')) ) AND (a.imsi = '460022517717646' OR a.peer_number = '460022517717646')
sql已简化为楼上所说,但是执行计划显示突然又不走索引了,这又是为何呢?SELECT a.start_time, a.report_time, a.imsi, a.cdrid FROM cdr_data_a20111024 a WHERE ( (a.start_time BETWEEN TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss') - 2 / 24 AND TO_DATE('2011-10-24 23:57:47', 'yyyy-mm-dd hh24:mi:ss')) AND (a.report_time > TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss')) ) AND (a.imsi = '460022517717646' OR a.peer_number = '460022517717646')
SELECT a.start_time, a.report_time, a.imsi, a.cdrid
FROM cdr_data_a20111024 a
WHERE EXISTS (
SELECT cdrid
FROM cdr_data_a20111024 b
WHERE (b.cdrid = a.cdrid OR b.base_cdrid = a.cdrid)
AND ( (b.start_time BETWEEN TO_DATE ('2011-10-24 08:07:47',
'yyyy-mm-dd hh24:mi:ss'
)
- 2 / 24
AND TO_DATE ('2011-10-24 23:57:47',
'yyyy-mm-dd hh24:mi:ss'
)
)
AND (b.report_time >
TO_DATE ('2011-10-24 08:07:47',
'yyyy-mm-dd hh24:mi:ss'
)
)
)
AND ( b.imsi IN ('460022517717646')
OR b.peer_number IN ('460022517717646')
))
AND ( (a.start_time BETWEEN TO_DATE ('2011-10-24 08:07:47',
'yyyy-mm-dd hh24:mi:ss'
)
- 2 / 24
AND TO_DATE ('2011-10-24 23:57:47',
'yyyy-mm-dd hh24:mi:ss'
)
)
AND (a.report_time >
TO_DATE ('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss')
)
)
AND (a.imsi='460022517717646' OR a.peer_number ='460022517717646'
)
193 | 0 (0)| 00:00:01 | | ||* 1 | FILTER | | |
| | | | || 2 | PARTITION RANGE ITERATOR | | 1 |
193 | 0 (0)| 00:00:01 | 7 | 24 ||* 3 | TABLE ACCESS BY LOCAL INDEX ROWID| CDR_DATA_A20111024 | 1 |
193 | 0 (0)| 00:00:01 | 7 | 24 ||* 4 | INDEX RANGE SCAN | IDX_CDR_DATA_A20111024 | 1 |
| 0 (0)| 00:00:01 | 7 | 24 || 5 | PARTITION RANGE ITERATOR | | 1 |
206 | 0 (0)| 00:00:01 | 7 | 24 ||* 6 | TABLE ACCESS BY LOCAL INDEX ROWID| CDR_DATA_A20111024 | 1 |
206 | 0 (0)| 00:00:01 | 7 | 24 ||* 7 | INDEX RANGE SCAN | IDX_CDR_DATA_A20111024 | 1 |
| 0 (0)| 00:00:01 | 7 | 24 |--------------------------------------------------------------------------------
----------------------------------------------------------
1 recursive calls
0 db block gets
11163067 consistent gets
0 physical reads
1128 redo size
1163 bytes sent via SQL*Net to client
349 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
16 rows processed
WITH w1 AS (
SELECT b.CDRID, b.BASE_CDRID, b.START_TIME, b.REPORT_TIME, b.IMSI
FROM CDR_DATA_A20111024 B
WHERE ((B.START_TIME BETWEEN
TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss') - 2 / 24 AND
TO_DATE('2011-10-24 23:57:47', 'yyyy-mm-dd hh24:mi:ss')) AND
(B.REPORT_TIME >
TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss')))
AND (B.IMSI IN ('460022517717646') OR
B.PEER_NUMBER IN ('460022517717646')))
SELECT T1.START_TIME, T1.REPORT_TIME, T1.IMSI, T1.CDRID
FROM W1 T1
WHERE EXISTS (SELECT T2.CDRID
FROM W1 T2
WHERE T1. CDRID = T2.CDRID
OR T1.BASE_CDRID = T2.BASE_CDRID)
a.report_time,
a.imsi,
a.cdrid
FROM cdr_data_a20111024 a
WHERE (
(a.start_time BETWEEN TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss') - 2 / 24 AND TO_DATE('2011-10-24 23:57:47', 'yyyy-mm-dd hh24:mi:ss')) AND
(a.report_time > TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss'))
)
AND (a.imsi = '460022517717646' OR a.peer_number = '460022517717646')
a.report_time,
a.imsi,
a.cdrid
FROM cdr_data_a20111024 a
WHERE (
(a.start_time BETWEEN TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss') - 2 / 24 AND TO_DATE('2011-10-24 23:57:47', 'yyyy-mm-dd hh24:mi:ss')) AND
(a.report_time > TO_DATE('2011-10-24 08:07:47', 'yyyy-mm-dd hh24:mi:ss'))
)
AND (a.imsi = '460022517717646' OR a.peer_number = '460022517717646')