About me:Oracle ACE pro,optimistic,passionate and harmonious. Focus on ORACLE,MySQL and other database programming,peformance tuning,db design, j2ee,Linux/AIX,Architecture tech,etc
全部博文(172)
分类: Oracle
2024-04-02 16:51:51
DROP TABLE t1; create table t1 as select to_char(trunc(dbms_random.value(10000000000, 20000000000 ))) phone_no, trunc(dbms_random.value(0, 30 )) ext, lpad(level,10) v1, rpad('x',100) padding from dual connect by level <= 1000000; DROP TABLE t2; create table t2 as select to_char(trunc(dbms_random.value(10000000000, 20000000000 ))) phone_no, trunc(dbms_random.value(0, 30 )) ext, lpad(level,10) v1, rpad('x',100) padding from dual connect by level <= 1000000; --创建索引 create index idx_t2 on t2(phone_no); --收集统计信息 exec DBMS_STATS.GATHER_TABLE_STATS(ownname=>user,tabname=>'t1',estimate_percent=>10,method_opt=>'for all columns size auto',no_invalidate=>false,cascade=>true,degree => 10); exec DBMS_STATS.GATHER_TABLE_STATS(ownname=>user,tabname=>'t2',estimate_percent=>10,method_opt=>'for all columns size auto',no_invalidate=>false,cascade=>true,degree => 10); 数据量: select count(*) from t1; COUNT(*) ---------- 1000000 select count(*) from t2; COUNT(*) ---------- 1000000 统计信息: TABLE_NAME NUM_ROWS SAMPLE_SIZE LAST_ANALYZED ------------------------------ ---------- ----------- ------------------- T1 1003550 100355 2023-08-18 17:13:11 T2 996380 99638 2023-08-18 17:13:11 |
SELECT phone_no,ext,v1,padding FROM t1 WHERE SUBSTR(t1.phone_no,1,8) IN (SELECT t2.phone_no FROM t2 WHERE LENGTH(t2.phone_no)=8) OR SUBSTR(t1.phone_no,1,9) IN (SELECT t2.phone_no FROM t2 WHERE LENGTH(t2.phone_no)=9) OR SUBSTR(t1.phone_no,1,10) IN (SELECT t2.phone_no FROM t2 WHERE LENGTH(t2.phone_no)=10) OR SUBSTR(t1.phone_no,1,11) IN (SELECT t2.phone_no FROM t2 WHERE LENGTH(t2.phone_no)=11); |
执行计划如下所示:
95 rows selected.
|
SELECT distinct t1.phone_no,t1.ext,t1.v1,t1.padding FROM t1,(SELECT DISTINCT phone_no FROM t2 WHERE LENGTH(t2.phone_no) BETWEEN 8 AND 11) t22 WHERE t1.phone_no LIKE t22.phone_no||'%' --构造HASH JOIN关键,{BANNED}最佳好重复值小,不然有HASH碰撞 AND SUBSTR(t1.phone_no,1,8)=SUBSTR(t22.phone_no,1,8) --下面的是防止其他不满足9-11的条件过滤,这个类似原来OR条件 AND SUBSTR(t1.phone_no,1,length(t22.phone_no))=t22.phone_no; |
95 rows selected. Elapsed: 00:00:00.88 Execution Plan ---------------------------------------------------------- Plan hash value: 555290710 --------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 139 | 6085 (3)| 00:01:14 | | 1 | HASH UNIQUE | | 1 | 139 | 6085 (3)| 00:01:14 | |* 2 | HASH JOIN | | 1 | 139 | 6084 (3)| 00:01:14 | |* 3 | INDEX FAST FULL SCAN| IDX_T2 | 2491 | 29892 | 882 (2)| 00:00:11 | | 4 | TABLE ACCESS FULL | T1 | 1003K| 121M| 5082 (1)| 00:01:01 | --------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access(SUBSTR("T1"."PHONE_NO",1,8)=SUBSTR("PHONE_NO",1,8)) filter("T1"."PHONE_NO" LIKE "PHONE_NO"||'%' AND "PHONE_NO"=SUBSTR("T1"."PHONE_NO",1,LENGTH("PHONE_NO"))) 3 - filter(LENGTH("T2"."PHONE_NO")>=8 AND LENGTH("T2"."PHONE_NO")<=11) Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 21748 consistent gets 18519 physical reads 0 redo size 4993 bytes sent via SQL*Net to client 586 bytes received via SQL*Net from client 8 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 95 rows processed |