欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mysql中in和exists的區(qū)別?&?not?in、not?exists、left?join的相互轉(zhuǎn)換問題

 更新時間:2023年09月16日 15:40:08   作者:心流時間  
這篇文章主要介紹了Mysql中in和exists的區(qū)別?&?not?in、not?exists、left?join的相互轉(zhuǎn)換,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

數(shù)據(jù)準備

-- 建表
CREATE TABLE `xin_stu_t_bak` (
  `id` bigint NOT NULL COMMENT '主鍵',
  `relation_id` bigint DEFAULT NULL COMMENT '外鍵, 記錄教師id',
  `student_name` varchar(30) DEFAULT NULL COMMENT '姓名',
  `student_age` bigint DEFAULT NULL COMMENT '年齡',
  `school` varchar(300) DEFAULT NULL COMMENT '學(xué)校',
  KEY `relationid` (`relation_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `xin_teach_t_bak` (
  `id` bigint NOT NULL COMMENT '主鍵',
  `teacher_name` varchar(30) DEFAULT NULL COMMENT '教師姓名',
  `teacher_age` bigint DEFAULT NULL COMMENT '教師年齡',
  `school` varchar(300) DEFAULT NULL COMMENT '學(xué)校',
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- 加索引
create index id on xin_stu_t_bak(relation_id);
create index id on xin_teach_t_bak(id);
-- 添數(shù)據(jù)
INSERT INTO lelele.xin_stu_t_bak (id,relation_id,student_name,student_age,school) VALUES
	 (1,NULL,'尤仁義1',11,'徐州中學(xué)'),
	 (2,1,'尤仁義2',12,'徐州中學(xué)'),
	 (3,NULL,'朱有理1',11,'徐州中學(xué)'),
	 (4,2,'朱有理2',12,'徐州中學(xué)'),
	 (5,2,'朱有理3',13,'徐州中學(xué)'),
	 (6,3,'宋昆明1',11,'徐州中學(xué)'),
	 (7,3,'宋昆明2',12,'徐州中學(xué)'),
	 (8,14,'宋昆明3',13,'徐州中學(xué)');
INSERT INTO lelele.xin_teach_t_bak (id,teacher_name,teacher_age,school) VALUES
	 (1,'王翠花1',31,'徐州中學(xué)'),
	 (2,'王翠花2',31,'徐州中學(xué)'),
	 (3,'王翠花3',33,'徐州中學(xué)'),
	 (4,'王翠花4',34,'徐州中學(xué)'),
	 (5,'王翠花5',35,'徐州中學(xué)'),
	 (1,'王翠花1',31,'徐州中學(xué)'),
	 (1,'王翠花1',31,'徐州中學(xué)'),
	 (2,'王翠花2',31,'徐州中學(xué)'),
	 (6,'王翠花6',31,'徐州中學(xué)'),
	 (7,'王翠花7',31,'徐州中學(xué)');
INSERT INTO lelele.xin_teach_t_bak (id,teacher_name,teacher_age,school) VALUES
	 (8,'王翠花8',33,'徐州中學(xué)'),
	 (9,'王翠花9',34,'徐州中學(xué)'),
	 (10,'王翠花10',35,'徐州中學(xué)'),
	 (11,'王翠花11',31,'徐州中學(xué)'),
	 (12,'王翠花12',31,'徐州中學(xué)'),
	 (13,'王翠花13',31,'徐州中學(xué)');

1. in 介紹

1.1 in中數(shù)據(jù)量的限制

在oracle中,int中數(shù)據(jù)集的大小超過1000會報錯;
在mysql中,超過1000不會報錯,但也是有數(shù)據(jù)量限制的,應(yīng)該是4mb,但不建議數(shù)據(jù)集超過1000,
因為in是可以走索引的,但in中數(shù)據(jù)量過大索引就會失效

1.2 null值不參與in或not in,也就是說in and not in 并不是全量值,排除了null值

select * from xin_stu_t_bak a where a.relation_id in ( select id from xin_teach_t_bak b)

在這里插入圖片描述

select * from xin_stu_t_bak a where a.relation_id not in ( select id from xin_teach_t_bak b)

在這里插入圖片描述

select * from xin_stu_t_bak a

在這里插入圖片描述

從此處可以看出,in和not in 加在一起并不是全量的值,排除了null值

1.3 in的執(zhí)行邏輯

  • 當前的in子查詢是B表驅(qū)動A表
  • mysql先將B表的數(shù)據(jù)一把查出來至于內(nèi)存中
  • 遍歷B表的數(shù)據(jù),再去查A表(每次遍歷都是一次連接交互,這里會耗資源)
  • 假設(shè)B有100000條記錄,A有10條記錄,會交互100000次數(shù)據(jù)庫;再假設(shè)B有10條記錄,A有100000記錄,只會發(fā)生10次交互。

結(jié)論: in是先進行子查詢,再與外面的數(shù)據(jù)進行循環(huán)遍歷,屬于子查詢的結(jié)果集驅(qū)動外面的結(jié)果集,
當in子查詢的結(jié)果集較小時,就形成了小表驅(qū)動大表,而兩張表的驅(qū)動就是一張表的行數(shù)據(jù)去循環(huán)關(guān)聯(lián)另一張表,
關(guān)聯(lián)次數(shù)越少越好,所以小表去查詢大表,次數(shù)更少,性能更高
in()適合B表比A表數(shù)據(jù)小的情況

2. exists介紹

2.1 exists + not exists 是全量數(shù)據(jù)

select * from xin_stu_t_bak a where exists ( select 1 from xin_teach_t_bak b where a.relation_id = b.id)

在這里插入圖片描述

select * from xin_stu_t_bak a where not exists ( select 1 from xin_teach_t_bak b where a.relation_id = b.id)

在這里插入圖片描述

exist + not exists 是全量數(shù)據(jù),這點與in不同

2.2 exists的執(zhí)行邏輯

  • 當前exists查詢是A表驅(qū)動B表
  • 與in不同,exists將A的紀錄數(shù)查詢到內(nèi)存,因此A表的記錄數(shù)決定了數(shù)據(jù)庫的交互次數(shù)
  • 假設(shè)A有10000條記錄,B有10條記錄,數(shù)據(jù)庫交互次數(shù)為10000;假設(shè)A有10條,B有10000條,數(shù)據(jù)庫交互次數(shù)為10。

結(jié)論:exists理論上就是boolean值,關(guān)聯(lián)后查詢到有值則是true數(shù)據(jù)留下,關(guān)聯(lián)后查詢沒有值則是false數(shù)據(jù)舍棄;exists適合B表數(shù)據(jù)量大,A表數(shù)據(jù)量小的情況,與in相反

3. 小表驅(qū)動大表的好處

我們來看下面兩個循環(huán):

for (int i = 0; i<10000; i++){ 
	for(int j = 0; j<10; j++){
	}
}
for (int i = 0; i<10; i++){ 
	for(int j = 0; j<10000; j++){
	}
}

在java中,我們都知道上述的兩個循環(huán)的時間復(fù)雜度都是一樣的;
但在數(shù)據(jù)庫中則是有區(qū)別的,
首先第一層循環(huán),數(shù)據(jù)庫只做一次交互一把將數(shù)據(jù)查出到緩存中,
而第二層循環(huán)的數(shù)據(jù)庫交互次數(shù)決定于第一層循環(huán)數(shù)據(jù)量的大小。
對于數(shù)據(jù)庫而言,交互次數(shù)越多越耗費資源,一次交互涉及了“連接-查找-斷開”這些操作,是相當耗費資源的。
使用in時,B表驅(qū)動A
使用exists時,A表驅(qū)動B
所以我們寫sql時應(yīng)當遵循“小表驅(qū)動大表“的原則

4. in、not in、exists、not exists是否可以走索引(都可以)

in可以走索引,但數(shù)據(jù)量過大時就不走索引了not in、exist、not exists也都可以走索引

in

select * from xin_stu_t_bak a where a.relation_id in ( select id from xin_teach_t_bak b where a.relation_id = b.id)

在這里插入圖片描述

select * from xin_stu_t_bak a where a.relation_id in (‘1', ‘2')

在這里插入圖片描述

not in

select * from xin_stu_t_bak a where a.relation_id not in (‘1', ‘2')

在這里插入圖片描述

exists

select * from xin_stu_t_bak a where exists ( select 1 from xin_teach_t_bak b where a.relation_id = b.id)

在這里插入圖片描述

not exists

select * from xin_stu_t_bak a where not exists ( select 1 from xin_teach_t_bak b where a.relation_id = b.id)

在這里插入圖片描述

5. not in、 not exists、left join語句相互轉(zhuǎn)換(必須在表關(guān)聯(lián)時,否則并不等同)

5.1 not in

select * from xin_stu_t_bak a where a.relation_id not in ( select id from xin_teach_t_bak b where a.relation_id = b.id)

在這里插入圖片描述

5.2 not exists

select * from xin_stu_t_bak a where not exists ( select 1 from xin_teach_t_bak b where a.relation_id = b.id)

在這里插入圖片描述

5.3 left join + is null

select a.* from xin_stu_t_bak a left join xin_teach_t_bak b on a.relation_id = b.id where b.id is null;

在這里插入圖片描述

到此這篇關(guān)于Mysql中in和exists的區(qū)別 & not in、not exists、left join的相互轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)Mysql中in和exists區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL中的CONCAT函數(shù)使用教程

    MySQL中的CONCAT函數(shù)使用教程

    這篇文章主要介紹了MySQL中的CONCAT函數(shù)使用教程,是Python入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-05-05
  • MySQL中having和where的區(qū)別及應(yīng)用詳解

    MySQL中having和where的區(qū)別及應(yīng)用詳解

    這篇文章主要給大家詳細介紹了MySQL中having和where的區(qū)別以及他們的使用方法,文中有相關(guān)的代碼示例,具有一定的參考價值,需要的朋友可以參考下
    2023-06-06
  • MySQL中varchar和char類型的區(qū)別

    MySQL中varchar和char類型的區(qū)別

    VARCHAR和CHAR是兩種最主要的字符串類型。那么MySQL中varchar和char類型的區(qū)別是什么,本文就具體來介紹一下,感興趣的可以了解一下
    2021-11-11
  • CentOS 7 安裝解壓版mysql5.7的教程

    CentOS 7 安裝解壓版mysql5.7的教程

    這篇文章主要介紹了CentOS 7 安裝解壓版mysql5.7的教程,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • mysql中GROUP_CONCAT函數(shù)使用技巧及問題詳解

    mysql中GROUP_CONCAT函數(shù)使用技巧及問題詳解

    這篇文章主要給大家介紹了關(guān)于mysql中GROUP_CONCAT函數(shù)使用技巧及問題的相關(guān)資料,GROUP_CONCAT是MySQL中的一個聚合函數(shù),它用于將多行數(shù)據(jù)按照指定的順序連接成一個字符串并返回結(jié)果,需要的朋友可以參考下
    2023-11-11
  • MySQL中LIKE?BINARY和LIKE模糊查詢實例代碼

    MySQL中LIKE?BINARY和LIKE模糊查詢實例代碼

    通常在實際應(yīng)用中,會涉及到模糊查詢的需求,下面這篇文章主要給大家介紹了關(guān)于MySQL中LIKE?BINARY和LIKE模糊查詢的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-11-11
  • mysql中的join和where優(yōu)先級順序解讀

    mysql中的join和where優(yōu)先級順序解讀

    這篇文章主要介紹了mysql中的join和where優(yōu)先級順序解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • MySQL在不知道列名情況下的注入詳解

    MySQL在不知道列名情況下的注入詳解

    這篇文章主要給大家介紹了關(guān)于MySQL在不知道列名情況下的注入的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用mysql具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Win7、WinXP下MySql安裝出錯完全卸載的方法步驟

    Win7、WinXP下MySql安裝出錯完全卸載的方法步驟

    這篇文章主要介紹了Win7、WinXP下MySql安裝出錯完全卸載的方法步驟,本文給出詳細的操作步驟,按本文方法清理后,重新安裝,應(yīng)該就不會有錯誤了,需要的朋友可以參考下
    2015-06-06
  • 解決hibernate+mysql寫入數(shù)據(jù)庫亂碼

    解決hibernate+mysql寫入數(shù)據(jù)庫亂碼

    初次沒習(xí)hibernate,其中遇到問題在網(wǎng)上找的答案與大家共同分享!
    2009-07-07

最新評論