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

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

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

數(shù)據(jù)準(zhǔn)備

-- 建表
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會(huì)報(bào)錯(cuò);
在mysql中,超過1000不會(huì)報(bào)錯(cuò),但也是有數(shù)據(jù)量限制的,應(yīng)該是4mb,但不建議數(shù)據(jù)集超過1000,
因?yàn)閕n是可以走索引的,但in中數(shù)據(jù)量過大索引就會(huì)失效

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í)行邏輯

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

結(jié)論: in是先進(jìn)行子查詢,再與外面的數(shù)據(jù)進(jìn)行循環(huán)遍歷,屬于子查詢的結(jié)果集驅(qū)動(dòng)外面的結(jié)果集,
當(dāng)in子查詢的結(jié)果集較小時(shí),就形成了小表驅(qū)動(dòng)大表,而兩張表的驅(qū)動(dòng)就是一張表的行數(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ù),這點(diǎn)與in不同

2.2 exists的執(zhí)行邏輯

  • 當(dāng)前exists查詢是A表驅(qū)動(dòng)B表
  • 與in不同,exists將A的紀(jì)錄數(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ū)動(dòng)大表的好處

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

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

in可以走索引,但數(shù)據(jù)量過大時(shí)就不走索引了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)時(shí),否則并不等同)

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)文章

  • MySQ實(shí)現(xiàn)XA事務(wù)的具體使用

    MySQ實(shí)現(xiàn)XA事務(wù)的具體使用

    XA事務(wù)是一種分布式事務(wù)處理協(xié)議,本文主要介紹了MySQ實(shí)現(xiàn)XA事務(wù)的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • 關(guān)于MySQL外鍵的簡單學(xué)習(xí)教程

    關(guān)于MySQL外鍵的簡單學(xué)習(xí)教程

    這篇文章主要介紹了關(guān)于MySQL外鍵的簡單學(xué)習(xí)教程,對InnoDB引擎下的外鍵約束做了簡潔的講解,需要的朋友可以參考下
    2015-11-11
  • MYSQL表中某字段所有值大小寫轉(zhuǎn)換

    MYSQL表中某字段所有值大小寫轉(zhuǎn)換

    這篇文章主要為大家介紹了MYSQL表中某字段所有值大小寫轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Mysql帶返回值與不帶返回值的2種存儲(chǔ)過程寫法

    Mysql帶返回值與不帶返回值的2種存儲(chǔ)過程寫法

    這篇文章主要介紹了Mysql帶返回值與不帶返回值的2種存儲(chǔ)過程寫法,需要的朋友可以參考下
    2017-10-10
  • Win7下mysql5.5安裝圖文教程

    Win7下mysql5.5安裝圖文教程

    這篇文章主要為大家詳細(xì)介紹了Win7下mysql5.5安裝的圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • mysql數(shù)據(jù)庫操作_高手進(jìn)階常用的sql命令語句大全

    mysql數(shù)據(jù)庫操作_高手進(jìn)階常用的sql命令語句大全

    mysql數(shù)據(jù)庫操作sql命令語句大全:三表連表查詢、更新時(shí)批量替換字段部分字符、判斷某一張表是否存在、自動(dòng)增長恢復(fù)從1開始、查詢重復(fù)記錄、更新時(shí)字段值等于原值加上一個(gè)字符串、更新某字段為隨機(jī)值、復(fù)制表數(shù)據(jù)到另一個(gè)表、創(chuàng)建表時(shí)拷貝其他表的數(shù)據(jù)和結(jié)構(gòu)...
    2022-11-11
  • 一文帶你學(xué)會(huì)MySQL的select語句

    一文帶你學(xué)會(huì)MySQL的select語句

    在MySQL中可以使用SELECT語句來查詢數(shù)據(jù),查詢數(shù)據(jù)是指從數(shù)據(jù)庫中根據(jù)需求,使用不同的查詢方式來獲取不同的數(shù)據(jù),是使用頻率最高、最重要的操作,下面這篇文章主要給大家介紹了關(guān)于MySQL中select語句的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • mysql格式化小數(shù)保留小數(shù)點(diǎn)后兩位(小數(shù)點(diǎn)格式化)

    mysql格式化小數(shù)保留小數(shù)點(diǎn)后兩位(小數(shù)點(diǎn)格式化)

    今天遇到一個(gè)問題,格式化浮點(diǎn)數(shù)的問題,用format(col,2)保留兩位小數(shù)點(diǎn),出現(xiàn)一個(gè)問題,例如下面的語句,后面我們給出解決方法
    2013-12-12
  • MySQL存儲(chǔ)過程的傳參和流程控制示例講解

    MySQL存儲(chǔ)過程的傳參和流程控制示例講解

    這篇文章主要介紹了MySQL存儲(chǔ)過程的傳參和流程控制示例講解,?repeat和Loop區(qū)別是repeat有自己退出循環(huán)的語句until,Loop使用的是if判斷語句,本文結(jié)合示例代碼詳細(xì)講解,需要的朋友可以參考下
    2023-02-02
  • MySQL子查詢原理的深入分析

    MySQL子查詢原理的深入分析

    子查詢指一個(gè)查詢語句嵌套在另一個(gè)查詢語句內(nèi)部的查詢,這個(gè)特性從 MySQL 4.1 開始引入,下面這篇文章主要介紹了MySQL子查詢原理的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01

最新評論