在 MSSQL 中,插入(insert)一條記錄很簡單,但是一些特殊應(yīng)用,在插入記錄前,需要檢查這條記錄是否已經(jīng)存在,只有當(dāng)記錄不存在時(shí)才執(zhí)行插入操作,本文介紹的就是這個(gè)問題的解決方案。
問題: 我創(chuàng)建了一個(gè)表來存放客戶信息,我知道可以用 insert 語句插入信息到表中,但是怎么樣才能保證不會(huì)插入重復(fù)的記錄呢?
答案: 可以通過使用 EXISTS 條件句防止插入重復(fù)記錄。
示例一:插入多條記錄
假設(shè)有一個(gè)主鍵為 client_id 的 clients 表,可以使用下面的語句:
Code:
個(gè)人批注:not exists不存在,也就是說后面的括號(hào)中只要返回了數(shù)據(jù)那么這個(gè)條件就不存在了,可以理解為括號(hào)前的not
exists是一個(gè)左表達(dá)式 ,括號(hào)后的查詢是一個(gè)右表達(dá)式,只有當(dāng)右表達(dá)式返回的也是not exists(即后面的查詢出來的結(jié)果是非空的)時(shí),等式才成立。
示例一:插入單條記錄
Code:
使用 dual 做表名可以讓你在 select 語句后面直接跟上要插入字段的值,即使這些值還不存在當(dāng)前表中。
系統(tǒng)要求進(jìn)行SQL優(yōu)化,對(duì)效率比較低的SQL進(jìn)行優(yōu)化,使其運(yùn)行效率更高,其中要求對(duì)SQL中的部分in/not in修改為exists/not exists
修改方法如下:
in的SQL語句
SELECT id, category_id, htmlfile, title, convert(varchar(20),begintime,112) as pubtime
FROM tab_oa_pub WHERE is_check=1 and
category_id in (select id from tab_oa_pub_cate where no='1')
order by begintime desc
修改為exists的SQL語句
SELECT id, category_id, htmlfile, title, convert(varchar(20),begintime,112) as pubtime
FROM tab_oa_pub WHERE is_check=1 and
exists (select id from tab_oa_pub_cate where tab_oa_pub.category_id=convert(int,no) and no='1')
order by begintime desc
分析一下exists真的就比in的效率高嗎?
我們先討論IN和EXISTS。
select * from t1 where x in ( select y from t2 )
事實(shí)上可以理解為:
select *
from t1, ( select distinct y from t2 ) t2
where t1.x = t2.y;
——如果你有一定的SQL優(yōu)化經(jīng)驗(yàn),從這句很自然的可以想到t2絕對(duì)不能是個(gè)大表,因?yàn)樾枰獙?duì)t2進(jìn)行全表的“唯一排序”,如果t2很大這個(gè)排序的性能是不可忍受的。但是t1可以很大,為什么呢?最通俗的理解就是因?yàn)閠1.x=t2.y可以走索引。但這并不是一個(gè)很好的解釋。試想,如果t1.x和t2.y都有索引,我們知道索引是種有序的結(jié)構(gòu),因此t1和t2之間最佳的方案是走merge join。另外,如果t2.y上有索引,對(duì)t2的排序性能也有很大提高。
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
——這個(gè)更容易理解,t1永遠(yuǎn)是個(gè)表掃描!因此t1絕對(duì)不能是個(gè)大表,而t2可以很大,因?yàn)閥=x.x可以走t2.y的索引。
綜合以上對(duì)IN/EXISTS的討論,我們可以得出一個(gè)基本通用的結(jié)論:IN適合于外表大而內(nèi)表小的情況;EXISTS適合于外表小而內(nèi)表大的情況。
我們要根據(jù)實(shí)際的情況做相應(yīng)的優(yōu)化,不能絕對(duì)的說誰的效率高誰的效率低,所有的事都是相對(duì)的
聯(lián)系客服