大表範圍掃描走SORT MERGE JOIN的SQL優化
SQL文字
select XXXXX
from t1 a
where 1 = 1
and a.flag = '0'
and a.flag2 = '1'
and exists (select 'x'
from t2 b
where b.startno <= t1_certno
and b.endno >= t1_certno
and balanceno in
(select c.balanceno
from t3 c
where 1 = 1
and c.proposalno = '50062000429971'))
order by a.t1_certno
邏輯讀排第一。這個 SQL由於是範圍掃描,因此只能走 SORT MERGE JOIN,幾個小時都跑不出結果。
靠固定執行計劃解決不了問題。
靠固定執行計劃解決不了問題。
要解決問題只能改程式。
![](http://img.blog.itpub.net/blog/attachment/201501/6/26239116_1420527736ALW0.png?x-oss-process=style/bb)
其實,給定 proposalno從 t3裡搜出來的資料一般只有幾行,而且每行資料的 startno和 endno也相差不遠。
因此可以將 b.startno <= t1_certno and b.endno >= t1_certno改成t1_certno in “t3裡每行的b.startno和 b.endno之間每一個值”。
也就是先找出所有的 t1_certno所有可能的取值,最後再通過索引從大表 t1找資料。
下面寫了一個方案,開發可以根據需要改寫成能和程式互動的方式,例如寫成函式,返回 table型別的資料等。
set serverout on
declare
tmp t2.startno%type;
i number;
len int;
begin
for c1 in ( select startno, endno from t2 b where balanceno in
(select c.balanceno
from t3 c
where 1 = 1
and c.proposalno = '50062000429971')
) loop
i := to_number(c1.startno);
len := length(c1.startno);
while i <= to_number(c1.endno) loop
-- dbms_output.put_line(lpad(to_char(i), len, '0'));
for c2 in (
select 要查的欄位
from t1 a
where 1 = 1
and a.flag = '0'
and a.flag2 = '1'
and t1_certno = lpad(to_char(i), len, '0')
order by a.t1_certno
) loop
dbms_output.put_line(c2.xxx||' '||c2.xxx||' '||c2.xxx||' '||c2.xxx||' '||c2.xxx||' '||c2.xxx||' '||c2.xxx);
end loop;
i:=i+1;
end loop;
end loop;
end;
/
![](http://img.blog.itpub.net/blog/attachment/201501/6/26239116_1420527746n393.png?x-oss-process=style/bb)
......
......
![](http://img.blog.itpub.net/blog/attachment/201501/6/26239116_1420527753l2FI.png?x-oss-process=style/bb)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26239116/viewspace-1392049/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle 全表掃描,索引範圍掃描與塊的理解Oracle索引
- 【sql調優之執行計劃】merge sort joinSQL
- 優化全表掃描優化
- 表的連線方式:NESTED LOOP、HASH JOIN、SORT MERGE JOIN(轉)OOP
- oracle sql tuning 8--優化全表掃描OracleSQL優化
- nested loop,sort merge join,hash joinOOP
- 【sql調優之執行計劃】merge join cartesian and buffer sortSQL
- oracle優化:避免全表掃描Oracle優化
- hash join\nest loop join\sort merge join的實驗OOP
- 優化Oracle with全表掃描的問題優化Oracle
- MySQL8.0之跳躍範圍掃描MySql
- 區域性範圍掃描的靈活應用
- 優化Oracle with全表掃描的問題(二)優化Oracle
- 【sql調優之執行計劃】merge semi join and merge anti joinSQL
- 查詢全表掃描的sqlSQL
- Oracle表連線操作——Merge Sort Join(合併排序連線)Oracle排序
- 有索引卻走全表掃描的實驗分析索引
- 排序合併連線(sort merge join)的原理排序
- mysql索引覆蓋掃描優化MySql索引優化
- SQL Server之旅(2):理解萬惡的表掃描SQLServer
- 一條全表掃描sql語句的分析SQL
- SonarQube系列-透過配置掃描分析範圍,聚焦關鍵問題
- MongoDB範圍查詢的索引優化MongoDB索引優化
- MySQL中的全表掃描和索引樹掃描MySql索引
- Oracle中存取資料掃描Table及索引的方式(全表掃描,索引掃描等)Oracle索引
- 使用全表掃描快取大表的相關問題快取
- Sql Server之旅——第二站 理解萬惡的表掃描SQLServer
- SQL 掃描引數(SARG)SQL
- Nested loops、Hash join、Sort merge join(三種連線型別原理、使用要點)OOP型別
- delete 與全表掃描delete
- Oracle Sort JoinOracle
- 理解資料庫掃描方法-利用掃描方法對資料儲存進行優化資料庫優化
- 高效的SQL(Index-Organized Tables優化精確查詢和範圍查詢)SQLIndexZed優化
- 微課sql最佳化(16)、表的連線方法(5)-關於Merge Join(排序合連線)SQL排序
- 使用索引快速全掃描(Index FFS)避免全表掃描的若干場景索引Index
- Oracle優化-索引原理[注意索引跳躍式掃描!Oracle優化索引
- BCSphere入門教程03:掃描周圍裝置
- 24_Oracle資料庫全表掃描詳解(四)_全表掃描生產最佳化案例三則Oracle資料庫