IN&EXISTS与NOT IN&NOT EXISTS 的优化原则小结
下面只是从理论上提出了一些建议,最好的原则是大家在上面的基础上,能够使用执行计划来分析,得出最佳的语句的写法。
1. EXISTS的执行流程select * from t1 where exists ( select null from t2 where y = x )
可以理解为:
代码如下:
for x in ( select * from t1 )
loop
if ( exists ( select null from t2 where y = x.x )
then
OUTPUT THE RECORD
end if
end loop
对于in 和 exists的性能区别:
如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in,反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。
其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了
另外IN时不对NULL进行处理,如:
select 1 from dual where null in (0,1,2,null)
结果为空。
2. NOT IN 与NOT EXISTS:
NOT EXISTS的执行流程
代码如下:
select .....
from rollup R
where not exists ( select 'Found' from title T
where R.source_id = T.Title_ID);
可以理解为:
代码如下:
for x in ( select * from rollup )
loop
if ( not exists ( that query ) ) then
OUTPUT
end if;
end;
注意:NOT EXISTS 与 NOT IN 不能完全互相替换,看具体的需求。如果选择的列可以为空,则不能被替换。
例如下面语句,看他们的区别:
select x,y from t;
x y
------ ------
1 3
3 1
1 2
1 1
3 1
5
select * from t where x not in (select y from t t2 )
no rows
select * from t where not exists (select null from t t2
where t2.y=t.x )
x y
------ ------
5 NULL
所以要具体需求来决定
对于not in 和 not exists的性能区别:
not in 只有当子查询中,select 关键字后的字段有not null约束或者有这种暗示时用not in,另外如果主查询中表大,子查询中的表小但是记录多,则应当使用not in,并使用anti hash join.
如果主查询表中记录少,子查询表中记录多,并有索引,可以使用not exists,另外not in最好也可以用/*+ HASH_AJ */或者外连接+is null
NOT IN 在基于成本的应用中较好
比如:
代码如下:
select .....
from rollup R
where not exists ( select 'Found' from title T
where R.source_id = T.Title_ID);
改成(佳)
select ......
from title T, rollup R
where R.source_id = T.Title_id(+)
and T.Title_id is null;
或者(佳)
sql> select /*+ HASH_AJ */ ...
from rollup R
where ource_id NOT IN ( select ource_id
from title T
where ource_id IS NOT NULL )
注意:上面只是从理论上提出了一些建议,最好的原则是大家在上面的基础上,能够使用执行计划来分析,得出最佳的语句的写法。
'//=============================
exists,not exists总结
1 exists
SELECT * FROM anken_m WHERE EXISTS(
SELECT my_list_temp_m.sales_code
FROM my_list_temp_m
WHERE my_list_temp_m.sales_code=anken_m.sales_code)
说明:
1) 查询在anken_m表和my_list_temp_m表中都存在的sales_code。
2) sales_code是anken_m的主键,my_list_temp_m的外键。
注意:
1) 外层查询表anken_m是查询的对象。
2) 内层查询表my_list_temp_m是条件对象。
3) 内外层的查询表不能相同。
4) 作为关联条件的anken_m表不需要在内层查询FROM后添加。
5) my_list_temp_m.sales_code=anken_m.sales_code条件的左右顺序不影响查询结果。
2 not exists
SELECT * FROM anken_m WHERE NOT EXISTS(
SELECT my_list_temp_m.sales_code
FROM my_list_temp_m
WHERE my_list_temp_m.sales_code=anken_m.sales_code)
说明:
1) 查询在anken_m表中存在,但是在my_list_temp_m表中不存在的sales_code。
2) sales_code是anken_m的主键,my_list_temp_m的外键。
注意:
1) 外层查询表anken_m是查询的对象。
2) 内层查询表my_list_temp_m是条件对象。
3) 内外层的查询表不能相同。
4) 作为关联条件的anken_m表不需要在内层查询FROM后添加。
5) my_list_temp_m.sales_code=anken_m.sales_code条件的左右顺序不影响查询结果。
3 综合运用
UPDATE anken_m
SET(plan_type_code, branch_name, business_type_code)
=(SELECT anken.plan_type_code,anken.branch_name,anken.business_type_code
FROM anken
WHERE anken.sales_code=anken_m.sales_code)
WHERE EXISTS (
SELECT anken.sales_code
FROM anken,my_list_temp_m
WHERE my_list_temp_m.sales_code=anken.sales_code
AND anken.sales_code=anken_m.sales_code
)
说明:
1) 用一个表的记录数据更新另一个表的记录数据。
2) 用一个SQL语句进行批量更新。
2) sales_code是anken,anken_m的主键,my_list_temp_m的外键。
注意:
1) set 语句中的要被更新字段必须跟数据源字段一一对应,另外数据源查询中的条件必须限定一条记录。也就是根据sales_code可以唯一确定anken的一条记录,和anken_m的一条记录,这样才能保证要被更新的记录和数据源记录的主键是相同的。
2) 根据WHERE EXISTS语句可以确定数据源记录的范围,也就是可以用anken表中哪些记录更新anken_m表。所以anken_m不需要在WHERE EXISTS语句中的FROM后添加。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

隨著國際化的不斷發展,越來越多的網站和應用程式需要支援多語言切換功能。 Vue作為一款流行的前端框架,提供了一個名為i18n的插件,可以幫助我們實現多語言切換。本文將介紹Vue中使用i18n實作多語言切換的常見技巧。第一步:安裝i18n插件首先,我們需要使用npm或yarn安裝i18n插件。在命令列中輸入以下命令:npminst

out介面指的是輸出接口,in接口指的是輸入接口。 out介面一般代表著音源線路輸出接口,用來接負載,例音箱、耳機等;而in接口一般代表著音源線路輸入接口,用來接CD機、手機、MP3、電腦等。

如何使用C#中的File.Exists函數判斷檔案是否存在在C#的檔案操作中,判斷檔案是否存在是基本的功能需求。 File.Exists函數是C#中的一個用來判斷檔案是否存在的方法。本文將介紹如何使用C#中的File.Exists函數來判斷檔案是否存在,並提供具體的程式碼範例。引用命名空間在開始編寫程式碼之前,首先需要引用System.IO命名空間,該命名空間

Mysqlon,in,as,where的區別答:Where查詢條件,on內外連接時候用,as作為別名,in查詢某值是否在某條件裡創建2個表:student,scorestudent:score:whereSELECT*FROMstudentWHEREs_sex='男'例如:onSELECT*FROMstudentLEFTJOINscoreonstudent.s_id=score.s_id;on和where組合:SELECT*FROMstudentLEFTJOINs

有使用者反映,在安裝了微軟3月份的Win11更新修補程式KB5035853後,出現了藍色畫面死機錯誤,其中系統頁面顯示「ThreadStuckinDeviceDriver」。據了解,這種錯誤可能是由硬體或驅動程式問題引起的。以下是五種修復方法,希望能夠快速解決電腦藍色畫面問題。方法一:執行系統檔案檢查在指令提示字元中執行【sfc/scannow】指令,可用來偵測和修復系統檔案的完整性問題。這個命令的作用是掃描並修復任何缺失或受損的系統文件,有助於確保系統的穩定性和正常運作。方法二:1.下載並開啟“藍色畫面修復工具”

Linux是一個強大的作業系統,有許多實用的指令和技巧可以幫助你更有效率地使用它。 1.查看檔案校驗值在檔案複製或傳輸過程中,可能會出現損壞或修改的情況,此時可以透過校驗值來進行驗證確認。通常,我們在工作中需要使用由其他團隊提供的一些介面程式。每當這些程式的運作結果與預期不符時,我們會比對雙方的md5校驗值以確認資料的一致性。產生檔案的校驗值的方法有很多種,常用的有md5sum校驗、crc校驗、sum校驗等。指令分別為:md5sumfile_namecksumfile_namesum演算法參數file

在實際開發中,網站或應用程式的多語言支援已成為必備的功能。 Vue作為一種流行的JavaScript框架,也支援多語言。本文將介紹Vue中多語言處理的方案與實作細節。方案選擇多語言的支援方案有很多種,包括但不限於以下幾種:1.1.前端整合式在前端實現多語言功能,透過vue-i18n插件支援。將對應語言包作為一個獨立組件引入,即可在不同語言環境下展示不同

MYSQL中EXISTS的用法,附帶程式碼範例在MYSQL資料庫中,EXISTS是一個非常有用的運算符,用來判斷一個子查詢是否至少回傳了一行資料。它通常與WHERE子句一起使用,以便根據子查詢的結果篩選出符合條件的資料。使用EXISTS需要注意以下幾點:EXISTS條件不關心子查詢傳回的特定數據,只關心是否有資料回傳。 EXISTS條件可以與其他的條件結合使用,
