成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MySQL查詢,是 join性能好,還是in一下更快呢?

數據庫 MySQL
當數據量小時,可能一頁數據就夠放的時候,join的成本和速度都更好。數據量大的時候確實分開查的成本更低,但是由于數據量大,造成循環的成本更多,代碼執行的時間也就越長。

先總結:

  1. 數據量小的時候,用join更劃算
  2. 數據量大的時候,join的成本更高,但相對來說join的速度會更快
  3. 數據量過大的時候,in的數據量過多,會有無法執行SQL的問題,待解決

事情是這樣的,在一次代碼review的時候有同學提出說,不要寫join,join耗性能還是慢來著,當時也是真的沒有多想,那就寫in好了,最近發現in的數據量過大的時候會導致sql慢,甚至sql太長,直接報錯了。

這次來淺究一下,到底是in好還是join好,僅目前認知探尋,有不對之處歡迎指正

以下實驗僅在本機電腦試驗。

一、表結構

1、用戶表

圖片圖片

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名',
  `gender` smallint DEFAULT NULL COMMENT '性別',
  `mobile` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '手機號',
  `create_time` datetime NOT NULL COMMENT '創建時間',
  PRIMARY KEY (`id`),
  UNIQUE KEY `mobile` (`mobile`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1005 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

2、訂單表

圖片圖片

CREATE TABLE `order` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `price` decimal(18,2) NOT NULL,
  `user_id` int NOT NULL,
  `product_id` int NOT NULL,
  `status` smallint NOT NULL DEFAULT '0' COMMENT '訂單狀態',
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `product_id` (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=202 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

二、先來試少量數據的情況

用戶表插一千條隨機生成的數據,訂單表插一百條隨機數據

查下所有的訂單以及訂單對應的用戶

下面從三個維度來看

多表連接查詢成本 = 一次驅動表成本 + 從驅動表查出的記錄數 * 一次被驅動表的成本

1、join

JOIN:

explain format=json select order.id, price, user.`name` from `order` join user on order.user_id = user.id;

子查詢:

select order.id,price,user.`name` from `order`,user where user_id=user.id;

圖片圖片

2、分開查

select `id`,price,user_id from `order`;

圖片圖片

select name from user where id in (8, 11, 20, 32, 49, 58, 64, 67, 97, 105, 113, 118, 129, 173, 179, 181, 210, 213, 215, 216, 224, 243, 244, 251, 280, 309, 319, 321, 336, 342, 344, 349, 353, 358, 363, 367, 374, 377, 380, 417, 418, 420, 435, 447, 449, 452, 454, 459, 461, 472, 480, 487, 498, 499, 515, 525, 525, 531, 564, 566, 580, 584, 586, 592, 595, 610, 633, 635, 640, 652, 658, 668, 674, 685, 687, 701, 718, 720, 733, 739, 745, 751, 758, 770, 771, 780, 806, 834, 841, 856, 856, 857, 858, 882, 934, 942, 983, 989, 994, 995);  \[in的是order查出來的所有用戶id\]

圖片圖片

如此看來,分開查和join查的成本并沒有相差許多

3、代碼層面

主要用php原生寫了腳本,用ab進行10個同時的請求,看下時間,進行比較

ab -n 100 -c 10

in

$mysqli = new mysqli('127.0.0.1', 'root', 'root', 'test');
 if ($mysqli->connect_error) {
     die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
 }

 $result = $mysqli->query('select `id`,price,user_id from `order`');
 $orders = $result->fetch_all(MYSQLI_ASSOC);

 $userIds = implode(',', array_column($orders, 'user_id')); // 獲取訂單中的用戶id
 $result = $mysqli->query("select `id`,`name` from `user` where id in ({$userIds})");
 $users = $result->fetch_all(MYSQLI_ASSOC);// 獲取這些用戶的姓名

 // 將id做數組鍵
 $userRes = [];
 foreach ($users as $user) {
     $userRes[$user['id']] = $user['name'];
 }

 $res = [];
 // 整合數據
 foreach ($orders as $order) {
     $current = [];
     $current['id'] = $order['id'];
     $current['price'] = $order['price'];
     $current['name'] = $userRes[$order['user_id']] ?: '';
     $res[] = $current;
 }
 var_dump($res);

 // 關閉mysql連接

 $mysqli->close();

圖片圖片

join

$mysqli = new mysqli('127.0.0.1', 'root', 'root', 'test');
if ($mysqli->connect_error) {
    die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}

$result = $mysqli->query('select order.id, price, user.`name` from `order` join user on order.user_id = user.id;');
$orders = $result->fetch_all(MYSQLI_ASSOC);

var_dump($orders);
$mysqli->close();

圖片圖片

看時間的話,明顯join更快一些

三、試下多一些數據的情況

user表現在10000條數據,order表10000條,試下

1、join

圖片圖片

2、分開

order

圖片圖片

user

圖片圖片

3、代碼層面

in

圖片圖片

join

圖片圖片

三、試下多一些數據的情況

隨機插入后user表十萬條數據,order表一百萬條試下

1、join

圖片圖片

2、分開

order

圖片圖片

user

order查出來的結果過長了,,,

3、代碼層面

in

圖片圖片

join

圖片圖片

四、到底怎么才能更好

注:對于本機來說100000條數據不少了,更大的數據量害怕電腦卡死

總的來說,當數據量小時,可能一頁數據就夠放的時候,join的成本和速度都更好。數據量大的時候確實分開查的成本更低,但是由于數據量大,造成循環的成本更多,代碼執行的時間也就越長。

實驗過程中發現,當in的數據量過大的時候,sql過長會無法執行,可能還要拆開多條sql進行查詢,這樣的查詢成本和時間一定也會更長,而且如果有分頁的需求的話,也無法滿足。。。

感覺這兩個方法都不是太好,各位小伙伴,有沒有更好的方法呢?

責任編輯:武曉燕 來源: 架構精進之路
相關推薦

2023-11-16 12:34:00

MySQLjoin

2018-08-20 15:00:32

Linux深度操作系統發行版

2021-11-09 08:57:13

元宇宙VR平行時空

2021-08-10 11:09:06

Linux壓縮神器命令

2021-04-27 07:52:18

SQLNULLOR

2023-06-20 12:02:39

WhileFor(;;)

2018-09-26 14:17:00

編程語言JavaPython

2018-10-09 15:26:19

JavaPython語言

2022-05-05 09:31:58

JOIN數據庫

2011-10-12 11:07:12

iCloudiOS5蘋果

2011-04-14 09:42:06

DataReaderDataSet

2020-04-06 14:50:43

MySQLSQL數據庫

2024-09-03 10:56:49

線程AQS

2025-01-15 08:05:06

MySQLLEFT JOIN數據庫

2023-08-18 20:50:22

2016-07-08 14:26:55

云計算

2023-06-05 14:14:21

騰訊索引面試

2016-12-06 09:12:07

Java程序員

2020-09-10 18:47:54

區塊鏈

2022-03-02 10:53:22

Postman工具開發
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品一区二区av | 亚洲一区二区三区免费在线观看 | 久久国产精品-久久精品 | 中文字幕在线电影观看 | 在线观看深夜视频 | 精品在线一区 | 国产精品成人一区二区三区 | 国产7777| 欧美性区 | 国产综合久久 | 日韩在线不卡视频 | 天天干天天想 | 国产成人免费视频网站高清观看视频 | 一区二区三区回区在观看免费视频 | 欧美激情精品久久久久久 | 久久久久久亚洲精品 | 欧美偷偷 | 91高清视频在线 | 一区二区三区四区电影视频在线观看 | 免费精品国产 | 伦理午夜电影免费观看 | 欧美亚洲网站 | 女人精96xxx免费网站p | 91久久爽久久爽爽久久片 | 狠狠视频| 91福利电影在线观看 | 天天干天天爱天天 | 久久久91精品国产一区二区三区 | 最新毛片网站 | 一区二区影视 | 一级视频黄色 | 国产精品视频在线播放 | 一级网站 | 日韩欧美国产一区二区三区 | 中文字幕亚洲无线 | 久久精品国产亚洲一区二区三区 | 精品国产区 | 日本中文字幕一区 | 国产在线视频一区 | 美日韩一区二区 | 精品久久久久久亚洲国产800 |