1. 程式人生 > >oracle中優化left join的工作心得

oracle中優化left join的工作心得

最近領導要求一個任務,大致可以如下解釋。

有A表和B表,兩個表均有ID和DATE欄位,A表儲存一個完整的數列SEQ,B表描述了A數列的某段所攜帶的資訊VAL,標記了起始數列號SEQ_START和終止數列號SEQ_END,要求生成一個根據B表標記A表指定數列VAL值的表

A表:

id     date              seq

1      2011/12/1   1

1      2011/12/1   2

1      2011/12/1   3

1      2011/12/2   1

1      2011/12/2   2

1      2011/12/2   3

2      2011/2/1      1

2      2011/2/1      2

2      2011/2/1      3

2      2011/2/1      4

B表:

id     date              seq_start     seq_end     val

1      2011/12/1   1                     2                   'val1'

1      2011/12/2   2                     3                   'val2'

2      2011/2/1     2                     3                   'val3'

完成表:

id     date              seq      val

1      2011/12/1   1           'val1'

1      2011/12/1   2           'val1'

1      2011/12/1   3

1      2011/12/2   1

1      2011/12/2   2           'val2'

1      2011/12/2   3           'val2'

2      2011/2/1      1

2      2011/2/1      2           'val3'

2      2011/2/1      3           'val3'

2      2011/2/1      4

根據以上條件寫的語句:

select e.*,f.completion_id,f.completion_name,f.completion_number,f.top_md,f.bottom_md
from (
	select c.jh,d.create_date,c.yczmc,c.xch,d.cds,c.syds,c.syhd,c.yxhd,c.yxstl,c.dcjsjg,c.skqk
	from [email protected] c,(
		select jh,create_date,
			count(completion_id) cds
		from (
			select a.well_desc jh,b.completion_id,
				to_date(to_char(b.create_date,'yyyy-MM-dd'),'yyyy-MM-dd') create_date
			from [email protected] a,[email protected] b
			where b.well_id=a.well_id
		)
		group by jh,create_date
	) d
	where c.jh=d.jh
) e left join (
	select a.well_desc jh,
		to_date(to_char(b.create_date,'yyyy-MM-dd'),'yyyy-MM-dd') create_date,
		b.completion_id,b.completion_name,b.completion_number,
		nvl(b.top_md,0) top_md,
		nvl(b.bottom_md,0) bottom_md
	from [email protected] a,[email protected] b
	where b.well_id=a.well_id
	order by a.well_desc
) f
on e.jh=f.jh and e.create_date=f.create_date and ((e.syds>=f.top_md and e.syds+e.syhd<=f.bottom_md) or (f.top_md=0 or f.bottom_md=0));

最後發現在最末端on的or條件開銷太大
on e.jh=f.jh and e.create_date=f.create_date and ((e.syds>=f.top_md and e.syds+e.syhd<=f.bottom_md) or (f.top_md=0 or f.bottom_md=0))


於是把left join儘量都改寫為where,同樣的執行結果,where的開銷遠比left join小

優化後的

select g.*,h.completion_id,h.completion_name,h.completion_number,h.top_md,h.bottom_md
from (
	select c.jh,d.create_date,c.yczmc,c.xch,d.cds,c.syds,c.syhd,c.yxhd,c.yxstl,c.dcjsjg,c.skqk
	from [email protected] c,(
		select jh,create_date,
			count(completion_id) cds
		from (
			select a.well_desc jh,b.completion_id,
				to_date(to_char(b.create_date,'yyyy-MM-dd'),'yyyy-MM-dd') create_date
			from [email protected] a,[email protected] b
			where b.well_id=a.well_id
		)
		group by jh,create_date
	) d
	where c.jh=d.jh
) g left join (
	select e.*,f.completion_id,f.completion_name,f.completion_number,f.top_md,f.bottom_md
	from (
		select c.jh,d.create_date,c.yczmc,c.xch,d.cds,c.syds,c.syhd,c.yxhd,c.yxstl,c.dcjsjg,c.skqk
		from [email protected] c,(
			select jh,create_date,
				count(completion_id) cds
			from (
				select a.well_desc jh,b.completion_id,
					to_date(to_char(b.create_date,'yyyy-MM-dd'),'yyyy-MM-dd') create_date
				from [email protected] a,[email protected] b
				where b.well_id=a.well_id
			)
			group by jh,create_date
		) d
		where c.jh=d.jh
	) e ,(
		select a.well_desc jh,
			to_date(to_char(b.create_date,'yyyy-MM-dd'),'yyyy-MM-dd') create_date,
			b.completion_id,b.completion_name,b.completion_number,
			nvl(b.top_md,0) top_md,
			nvl(b.bottom_md,0) bottom_md
		from [email protected] a,[email protected] b
		where b.well_id=a.well_id
		order by a.well_desc
	) f
	where e.jh=f.jh and e.create_date=f.create_date and ((e.syds>=f.top_md and e.syds+e.syhd<=f.bottom_md) or (f.top_md=0 or f.bottom_md=0))
) h
on g.jh=h.jh and g.create_date=h.create_date and g.xch=h.xch and g.syds=h.syds;



這樣就是人類能忍受的程度了

相關推薦

oracle優化left join工作心得

最近領導要求一個任務,大致可以如下解釋。 有A表和B表,兩個表均有ID和DATE欄位,A表儲存一個完整的數列SEQ,B表描述了A數列的某段所攜帶的資訊VAL,標記了起始數列號SEQ_START和終止數列號SEQ_END,要求生成一個根據B表標記A表指定數列VAL值的表 A

oracle 常用的 join on 相關和 集合運算的總結

nal 但是 總結 rom 全部 right light style 是把 sql常用聯合查詢的 join on 、 left join(左連接) 、 right join (右連接)、inner join (等值連接)以及常用的集合運算有:union、unionall、m

Oracle,用left join 替代 exists ,not exists,in , not in,提高效率

.cn rom mage png 高效 pan div sele bsp Not IN問題 Exists,not Exists,in,not in 例如: DELETE FROM YSHA WHERE NOT EXISTS(SELECT 1 FROM YSHB B

記一次sql優優化——left join不走索引問題

alt 卡住 image sql col ima cnblogs 優化 .cn sql一執行就卡住,然後就...殺進程了 看了一下表的大小 第一反應就是加索引,然後explain看了一下走什麽索引了,結果很尷尬,三個表,只走了一個索引...一群人在那糾結為毛走不了索引。

MySQL、SQLServer、Oracle的update left join語法

server left join _id pda 語法 HERE lse code lec mysql UPDATE A LEFT JOIN B ON A.B_ID = B.B_ID SET A.A_NAME = B.B_NAME; s

MapReduce在Reduce實現LEFT JOIN

本文以訂單和商品演示如何實現left join。 一:準備資料 訂單資料表t_order: id date pid amount 1001 20150710 P0

LeetCode-175. 組合兩個表(SQL語句LEFT JOIN)

題目連結: 組合兩個表 題目描述: 表1: Person +-------------+---------+ | 列名 | 型別 | +-------------+---

關於Linq to Sql left join defaultifempty的相關注意事項

            var q = (from c in                          (from a1 in db.StoreIns                           group a1 by a1.StoreNum into g                 

oracle的hash join

hash join是oracle裡面一個非常強悍的功能,當做hash join時,oracle會選擇一個表作為驅動表,先根據過濾條件排除不必要的資料,然後將結果集做成hash表,放入程序的hash area,接著掃描第二張表,將行的鍵值做hash運算,到記憶體的hash

SQL left join 外連線

left join 是 left outer join 的簡寫,left join 預設是 outer 屬性的。 account 表 custom 表 0 基礎 inner join left join 外連線包括

mysql 如何優化left join

今天遇到一個left join優化的問題,搞了一下午,中間查了不少資料,對MySQL的查詢計劃還有查詢優化有了更進一步的瞭解,做一

Oracleleft join使用子查詢( ORA-01799: 列不能外部聯接到子查詢)

informix改oracle遇到一個問題。注意:left join的第二張表,有多條資料,只取符合條件的一條(本例中取出actn_numb最大的一條記錄)。   基礎資料準備: create table A(     id number primar

oracleleft join,right join,inner join的坑

本文主要是記錄一下實際使用oracle中join查詢遇到的坑 1.用到兩張表,學生表和學年分數表,先建立 2.普通連線查詢 INNER JOIN,查詢每個學年有成績的學生以及分數情況 LFET JOIN 和 RIGHT JOIN 也類似,不舉例了。   以下重點是說以下,連線的時

Oracleleft joinon和where的區別以及與(+)的區別

資料庫在通過連線兩張或多張表來返回記錄時,都會生成一張中間的臨時表,然後再將這張臨時表返回給使用者。       在使用left jion時,on和where條件的區別如下: 1、 on條件是在生成臨時表時使用的條件,它不管on中的條件是否為真,都會返回左邊表中的記錄。 2、where條件是在臨時表生成好後

★★★ oracle外連線,OracleLeft Outer Join和外關聯(+)的區別

【原】Oracle中Left Outer Join和外關聯(+)的區別 2008-03-23 16:22:37 Oracle的left join中on和where的區別 2009-09-28 15:20 今天遇到一個求某月所有天數的統計結果,如果某日的結果是0

Oracleleft join中右表的限制條件

無過濾條件的LEFT JOIN SQL中最簡單形式的LEFT JOIN,是直接根據關聯欄位,以左表為基準,對右表進行匹配。在SELECT語句中選取的欄位,如果有右表的記錄(一般都是需要右表的某些記錄的),取出配對成功的右表記錄中對應的這個欄位的值;否則,直接置NULL。這本身就是LEFT JOIN的特點

Oracleleft joinon和where的區別

資料庫在通過連線兩張或多張表來返回記錄時,都會生成一張中間的臨時表,然後再將這張臨時表返回給使用者。     在使用left jion時,on和where條件的區別如下:     1、on條件是在生成臨時表時使用的條件,它不管on中的條件是否為真,都會返回左邊表中的記

oracle各種連線(left join,right join,inner join)用法

left join:左連線,返回左表中所有的記錄以及右表中連線欄位相等的記錄。 right join :右連線,返回右表中所有的記錄以及左表中連線欄位相等的記錄。 inner join :內連線,又叫等值連線,只返回兩個表中連線欄位相等的行。 full join:外連

MysqlLeft Join 與Right Join 與 Inner Join 與 Full Join的區別

chinese ron 兩張 ansi 左連接 ima money key sel 看看Left Join 與Right Join 與 Inner Join 與 Full Join對表進行操作後得到的結果。 在數據庫中新建兩張表,並插入要測試的數據。 新建表:

MySQL分頁優化的“INNER JOIN方式優化分頁算法”到底在什麽情況下會生效?

表結構 files key 效率 ref 兩個 ges 參考 如果 本文出處:http://www.cnblogs.com/wy123/p/7003157.html 最近無意間看到一個MySQL分頁優化的測試案例,並沒有非常具體地說明測試場景的情況下,給出了