国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

深圳 微網(wǎng)站建設ydgcm獎券世界推廣網(wǎng)站

深圳 微網(wǎng)站建設ydgcm,獎券世界推廣網(wǎng)站,武漢網(wǎng)站建設求職簡歷,濟南建站公司價格文章目錄1. 文章引言2. 查詢對比2.1 in和exists2.2 not in 和not exists2.3 in 與 的區(qū)別3. 性能分析3.1 in和exists3.2 NOT IN 與NOT EXISTS4. 重要總結1. 文章引言 我們在工作的過程中,經(jīng)常使用in,not in,exists,not exists來…

文章目錄

  • 1. 文章引言
  • 2. 查詢對比
    • 2.1 in和exists
    • 2.2 not in 和not exists
    • 2.3 in 與 = 的區(qū)別
  • 3. 性能分析
    • 3.1 in和exists
    • 3.2 NOT IN 與NOT EXISTS
  • 4. 重要總結

1. 文章引言

我們在工作的過程中,經(jīng)常使用in,not in,exists,not exists來查詢,比如現(xiàn)在一張項目(project)表,表的結構和數(shù)據(jù):

CREATE TABLE `project` (`id` int(11) NOT NULL AUTO_INCREMENT,`status` varchar(255) DEFAULT NULL,`project_name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;INSERT INTO `project` VALUES ('1', 'finish', '太湖佳園');
INSERT INTO `project` VALUES ('2', 'during', '尚東雅園');
INSERT INTO `project` VALUES ('3', 'start', '水鄉(xiāng)苑一區(qū)');
INSERT INTO `project` VALUES ('4', 'during', '水鄉(xiāng)苑二區(qū)');

查詢狀態(tài)為已完成和進行中的記錄,我們可以寫成如下的SQL語句:

select * from project where `status` in ('finish','during');

查詢結果如下圖:

在這里插入圖片描述

這只是我們開發(fā)中的一個簡單示例,接下來,我們詳細解說 in與not in,exists與not exists的區(qū)別以及性能分析。

2. 查詢對比

2.1 in和exists

in是把外表和內表作hash連接。

exists是對外表作loop循環(huán),每次loop循環(huán)再對內表進行查詢,一直以來認為existsin效率高的說法是不準確的。

如果查詢的兩個表大小相當,那么用inexists差別不大。

如果兩個表中一個較小一個較大,則子查詢表大的用exists,子查詢表小的用in

例如:表A(小表),表B(大表)


-- 效率低,用到了A表上cc列的索引
select * from A where cc in(select cc from B)  -- 效率高,用到了B表上cc列的索引
select * from A where exists(select cc from B where cc=A.cc) 

相反的:


-- 效率高,用到了B表上cc列的索引
select * from B where cc in(select cc from A) -- 效率低,用到了A表上cc列的索引。
select * from B where exists(select cc from A where cc=B.cc)  

2.2 not in 和not exists

not in邏輯上不完全等同于not exists,如果你誤用了not in小心你的程序存在致命的BUG,請看下面的例子:

-- 創(chuàng)建t1表
create table t_1(c1 int,c2 int);-- 創(chuàng)建t2表
create table t_2(c1 int,c2 int);-- 向t1表中插入數(shù)據(jù)
insert into t_1 values(1,2);
insert into t_1 values(1,3);-- 向t2表中插入數(shù)據(jù)
insert into t_2 values(1,2);
insert into t_2 values(1,null); 

先后執(zhí)行如下兩條查詢語句:

  1. 語句1
SELECT*
FROMt_1
WHEREc2 NOT IN (SELECT c2 FROM t_2);

查詢結果是空值,如下圖:

在這里插入圖片描述

  1. 語句2
SELECT*
FROMt_1
WHERENOT EXISTS (SELECT1FROMt_2WHEREt_2.c2 = t_1.c2);

查詢結果c1 = 1,c2 = 3,如下圖所示:

在這里插入圖片描述

正如你所看到的,not in出現(xiàn)了不期望的結果集,存在邏輯錯誤。

如果看一下上述兩個select語句的執(zhí)行計劃,也會不同,語句2使用了hash_aj,所以,請盡量不要使用not in(它會調用子查詢),而盡量使用not exists(它會調用關聯(lián)子查詢)。

如果子查詢中返回的任意一條記錄含有空值,則查詢將不返回任何記錄。

如果子查詢字段有非空限制,這時可以使用not in,并且可以通過提示讓它用hasg_ajmerge_aj連接。

如果查詢語句使用了not in,那么對內外表都進行全表掃描,沒有用到索引。而not exists的子查詢依然能用到表上的索引。所以無論哪個表大,用not exists都比not in 要快。

2.3 in 與 = 的區(qū)別


SELECTNAME
FROMstudent
WHERENAME IN ('zhang', 'wang', 'zhao');

SELECTNAME
FROMstudent
WHERENAME = 'zhang'
OR NAME = 'wang'
OR NAME = 'zhao'

的結果是相同的。

3. 性能分析

3.1 in和exists

  1. EXISTS的執(zhí)行流程
SELECT*
FROMt1
WHEREEXISTS (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 
  1. inexists的性能區(qū)別

如果子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用in。

反之,如果外層的主查詢記錄較少,子查詢中的表大,又有索引時使用exists

其實我們區(qū)分inexists主要是造成了驅動順序的改變(這是性能變化的關鍵):

  • 如果是exists,那么以外層表為驅動表,先被訪問

  • 如果是IN,那么先執(zhí)行子查詢

所以我們會以驅動表的快速返回為目標,那么就會考慮到索引及結果集的關系了 。

另外,IN時不對NULL進行處理,如下SQL所示:

SELECT1
FROMDUAL
WHERENULL IN (0, 1, 2, NULL)

查詢結果為空。

3.2 NOT IN 與NOT EXISTS

  1. NOT EXISTS的執(zhí)行流程
SELECT.....
FROMROLLUP R
WHERENOT EXISTS (SELECT'Found'FROMtitle TWHERER.source_id = T.Title_ID);

可以理解為:

for x in ( select * from rollup ) loop 
if ( not exists ( that query ) ) then 
OUTPUT 
end if; 
end loop; 

注意:NOT EXISTSNOT IN不能完全互相替換,看具體的需求。如果選擇的列可以為空,則不能被替換。

例如下面語句,看他們的區(qū)別:

select x,y from t; 

查詢xy數(shù)據(jù)如下所示:

x      y 
------ ------ 
1      3 
3      1 
1      2 
1      1 
3      1 
5 
  1. 使用not innot exists查詢結果,如下
SELECT*
FROMt
WHEREx NOT IN (SELECT y FROM t t2);

查詢無結果:no rows

SELECT*
FROMt
WHERENOT EXISTS (SELECTNULLFROMt t2WHEREt2.y = t.x);

查詢結果為:

x       y 
------ ------ 
5      NULL 

所以要具體需求來決定

  1. not innot exists的性能區(qū)別

not in只有當子查詢中,select關鍵字后的字段有not null約束,或者有這種暗示時用not in。另外,如果主查詢中表大,子查詢中的表小但是記錄多,則應當使用not in,并使用anti hash join。

如果主查詢表中記錄少,子查詢表中記錄多,并有索引,可以使用not exists,另外,not in最好也可以用/*+ HASH_AJ */或者外連接+is null。

NOT IN在基于成本的應用中較好,比如:

SELECT.....
FROMROLLUP R
WHERENOT EXISTS (SELECT'Found'FROMtitle TWHERER.source_id = T.Title_ID);

最好修改成如下方式:

SELECT......
FROMtitle T,ROLLUP R
WHERER.source_id = T.Title_id (+)
AND T.Title_id IS NULL;

或者(佳):

SELECT/*+ HASH_AJ */...
FROMROLLUP R
WHEREource_id NOT IN (SELECTource_idFROMtitle TWHEREource_id IS NOT NULL)

4. 重要總結

討論INEXISTS。

select * from t1 where x in ( select y from t2 ) 

事實上可以理解為:

SELECT*
FROMt1,(SELECT DISTINCT y FROM t2) t2
WHEREt1.x = t2.y;

如果你有一定的SQL優(yōu)化經(jīng)驗,從這句很自然的可以想到t2絕對不能是個大表,因為需要對t2進行全表的唯一排序。

如果t2很大,這個排序的性能是不可忍受的,但是t1可以很大,為什么呢?

最通俗的理解就是因為t1.x=t2.y可以走索引。但這并不是一個很好的解釋。

試想,如果t1.xt2.y都有索引,我們知道索引是種有序的結構,因此t1t2之間最佳的方案是走merge join

另外,如果t2.y上有索引,對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 

這個更容易理解,t1永遠是個表掃描!因此t1絕對不能是個大表,而t2可以很大,因為y=x.x可以走t2.y的索引。

綜合以上對IN/EXISTS的討論,我們可以得出一個基本通用的結論:

  1. IN適合于外表大而內表小的情況;
  2. EXISTS適合于外表小而內表大的情況。

我們要根據(jù)實際的情況做相應的優(yōu)化,不能絕對的說誰的效率高誰的效率低,所有的事都是相對的

http://m.aloenet.com.cn/news/33451.html

相關文章:

  • 如何判斷網(wǎng)站html5上海高端seo公司
  • 網(wǎng)站開源模板百度指數(shù)排名明星
  • app平臺網(wǎng)站搭建潮州seo建站
  • 雙語網(wǎng)站建設報價百度鏈接提交收錄入口
  • dw網(wǎng)頁設計期末作業(yè)seo的主要分析工具
  • 公司網(wǎng)站設計方案網(wǎng)站查詢是否安全
  • 天津做網(wǎng)站哪個公司好seo排名優(yōu)化工具推薦
  • 做游戲開發(fā)需要學哪些技術優(yōu)化大師下載安裝app
  • 網(wǎng)站建設 長沙百度推廣怎么提高關鍵詞排名
  • 勝芳網(wǎng)站建設qiansi全國疫情最新情況公布
  • 前端怎么做電商網(wǎng)站網(wǎng)絡營銷和網(wǎng)絡銷售的關系
  • 做論壇網(wǎng)站需要哪些前置審批申請一個網(wǎng)站需要多少錢
  • 網(wǎng)站域名備案需要資料網(wǎng)站內鏈優(yōu)化
  • 專業(yè)的營銷型網(wǎng)站最新報價網(wǎng)絡推廣策劃
  • 怎么給網(wǎng)站做aapseo優(yōu)化專家
  • 廈網(wǎng)站建設培訓學校創(chuàng)建網(wǎng)站要錢嗎
  • 做外貿網(wǎng)站需要什么卡西安網(wǎng)站快速排名提升
  • 外貿需要網(wǎng)站做生產車間展示友聯(lián)互換
  • 網(wǎng)站規(guī)劃與設計范文seo招聘網(wǎng)
  • 什么樣建網(wǎng)站百度的seo排名怎么刷
  • 建站之星怎么用國外網(wǎng)站搭建
  • 網(wǎng)站 css江門百度seo公司
  • 東莞市建設網(wǎng)站首頁百度怎樣發(fā)布作品
  • app開發(fā)及后期維護費用重慶企業(yè)站seo
  • 陜西省建設廳網(wǎng)站三類b證磁力蜘蛛
  • 怎么做網(wǎng)絡推廣營銷seo專員的工作內容
  • 商務網(wǎng)站建設實訓報告網(wǎng)絡銷售面試問題有哪些
  • 男人互做網(wǎng)站關鍵詞排名靠前
  • 金華建設學校繼續(xù)教育網(wǎng)站廣東培訓seo
  • 企業(yè)模擬網(wǎng)站建設本地推廣平臺有哪些