亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

聊聊MySQL的COUNT(*)的性能

 更新時(shí)間:2020年11月29日 09:44:58   作者:god-jiang  
這篇文章主要介紹了聊聊MySQL的COUNT(*)的性能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

基本職場(chǎng)上的程序員用來(lái)統(tǒng)計(jì)數(shù)據(jù)庫(kù)表的行數(shù)都會(huì)使用count(*),count(1)或者count(主鍵),那么它們之間的區(qū)別和性能你又是否了解呢?

其實(shí)程序員在開(kāi)發(fā)的過(guò)程中,在一張大表上統(tǒng)計(jì)總行數(shù)是非常耗時(shí)的一個(gè)操作,那么我們應(yīng)該用哪個(gè)方法統(tǒng)計(jì)會(huì)更快呢?

接下來(lái)我們就來(lái)聊一聊MySQL中統(tǒng)計(jì)總行數(shù)的方法和性能。

count(*),count(1),count(主鍵)哪個(gè)更快?

1、建表并且插入1000萬(wàn)條數(shù)據(jù)進(jìn)行實(shí)驗(yàn)測(cè)試:

# 創(chuàng)建測(cè)試表
CREATE TABLE `t6` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(50) NOT NULL,
 `status` tinyint(4) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

# 創(chuàng)建存儲(chǔ)過(guò)程插入1000w數(shù)據(jù)
CREATE PROCEDURE insert_1000w()
BEGIN
  DECLARE i INT;
  SET i=1;
  WHILE i<=10000000 DO
    INSERT INTO t6(name,status) VALUES('god-jiang-666',1);
    SET i=i+1;
  END WHILE;
END;

#調(diào)用存儲(chǔ)過(guò)程,插入1000萬(wàn)行數(shù)據(jù)
call insert_1000w();

2、分析實(shí)驗(yàn)結(jié)果

# 花了0.572秒
select count(*) from t6;

在這里插入圖片描述

# 花了0.572秒
select count(1) from t6;

在這里插入圖片描述

# 花了0.580秒
select count(id) from t6;

在這里插入圖片描述

# 花了0.620秒
select count(*) from t6 force index (primary);

在這里插入圖片描述

從上面的實(shí)驗(yàn)我們可以得出,count(*)和count(1)是最快的,其次是count(id),最慢的是count使用了強(qiáng)制主鍵的情況。

下面我們繼續(xù)測(cè)試一下它們各自的執(zhí)行計(jì)劃:

explain select count(*) from t6;
show warnings;

在這里插入圖片描述

在這里插入圖片描述

explain select count(1) from t6;
show warnings;

在這里插入圖片描述

在這里插入圖片描述

explain select count(id) from t6;
show warnings;

在這里插入圖片描述

在這里插入圖片描述

explain select count(*) from t6 force index (primary);
show warnings;

在這里插入圖片描述

在這里插入圖片描述

從上面的實(shí)驗(yàn)可以得出這三點(diǎn):

  1. count(*)被MySQL查詢優(yōu)化器改寫(xiě)成了count(0),并選擇了idx_status索引
  2. count(1)和count(id)都選擇了idx_statux索引
  3. 加了force index(primary)之后,走了強(qiáng)制索引

這個(gè)idx_status就是相當(dāng)于是二級(jí)輔助索引樹(shù),目的就是為了說(shuō)明: InnoDB在處理count(*)的時(shí)候,有輔助索引樹(shù)的情況下,會(huì)優(yōu)先選擇輔助索引樹(shù)來(lái)統(tǒng)計(jì)總行數(shù)。

為了驗(yàn)證count(*)會(huì)優(yōu)先選擇輔助索引樹(shù)這個(gè)結(jié)論,我們繼續(xù)來(lái)看看下面的實(shí)驗(yàn):

# 刪除idx_status索引,繼續(xù)執(zhí)行count(*)
alter table t6 drop index idx_status;

explain select count(*) from t6;

在這里插入圖片描述

從以上實(shí)驗(yàn)可以得出,刪除了idx_status這個(gè)輔助索引樹(shù),count(*)就會(huì)選擇走主鍵索引。所以結(jié)論:count(*)會(huì)優(yōu)先選擇輔助索引,假如沒(méi)有輔助索引的存在,就會(huì)走主鍵索引。

為什么count(*)會(huì)優(yōu)先選擇輔助索引?

在MySQL5.7.18之前,InnoDB通過(guò)掃描聚集索引來(lái)處理count(*)語(yǔ)句。

從MySQL5.7.18開(kāi)始,InnoDB通過(guò)遍歷最小的可用二級(jí)索引來(lái)處理count(*)語(yǔ)句。如果不存在二級(jí)索引,則掃描聚集索引。

新版本為何會(huì)使用二級(jí)索引來(lái)處理count(*)呢?

因?yàn)镮nnoDB二級(jí)索引樹(shù)的葉子節(jié)點(diǎn)上存放的是主鍵,而主鍵索引樹(shù)的葉子節(jié)點(diǎn)存放的是整行數(shù)據(jù),所以二級(jí)索引樹(shù)比主鍵索引樹(shù)小。因此查詢優(yōu)化器基于成本考慮,優(yōu)先選擇的是二級(jí)索引。所以索引count(*)快于count(主鍵)。

總結(jié)

這篇文章的結(jié)論就是count(*)=count(1)>count(id)。

為什么count(id)走了主鍵索引還會(huì)更慢呢?因?yàn)閏ount(id)需要取出主鍵,然后判斷不為空,再累加,代價(jià)更高。

count(*)是會(huì)總計(jì)出所有NOT NULL和NULL的字段,而count(id)是不會(huì)統(tǒng)計(jì)NULL字段的,所以我們?cè)诮ū淼谋M量使用NOT NULL并且給它一個(gè)默認(rèn)是空即可。

最后,在以后總計(jì)數(shù)據(jù)庫(kù)表的總行數(shù)的時(shí)候,可以大膽的使用count(*)或者count(1)。

參考資料

  • 《高性能MySQL》(第三版)第六章優(yōu)化COUNT()查詢
  • 《MySQL實(shí)戰(zhàn)45講》林曉斌

到此這篇關(guān)于聊聊MySQL的COUNT(*)的性能的文章就介紹到這了,更多相關(guān)MySQL COUNT(*)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解MySQL中default的使用

    詳解MySQL中default的使用

    這篇文章主要介紹了MySQL中default的使用,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-05-05
  • 關(guān)于MySQL 優(yōu)化的100個(gè)的建議

    關(guān)于MySQL 優(yōu)化的100個(gè)的建議

    MYSQL 如此方便和穩(wěn)定,以至于我們?cè)陂_(kāi)發(fā) WEB 程序的時(shí)候很少想到它。即使想到優(yōu)化也是程序級(jí)別的,比如,不要寫(xiě)過(guò)于消耗資源的 SQL 語(yǔ)句。但是除此之外,在整個(gè)系統(tǒng)上仍然有很多可以優(yōu)化的地方。
    2016-01-01
  • MySQL InnoDB存儲(chǔ)引擎的深入探秘

    MySQL InnoDB存儲(chǔ)引擎的深入探秘

    這篇文章主要給大家介紹了關(guān)于MySQL InnoDB存儲(chǔ)引擎的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • MySQL字符串的拼接、截取、替換、查找位置實(shí)例詳解

    MySQL字符串的拼接、截取、替換、查找位置實(shí)例詳解

    MySQL中的字符串操作包括拼接、截取、替換和查找位置等功能,本文給大家介紹MySQL字符串的拼接、截取、替換、查找位置示例詳解,感興趣的朋友一起看看吧
    2024-09-09
  • MySQL使用IF語(yǔ)句及用case語(yǔ)句對(duì)條件并結(jié)果進(jìn)行判斷?

    MySQL使用IF語(yǔ)句及用case語(yǔ)句對(duì)條件并結(jié)果進(jìn)行判斷?

    這篇文章主要介紹了MySQL使用IF語(yǔ)句及用case語(yǔ)句對(duì)條件并結(jié)果進(jìn)行判斷,文章通過(guò)圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • 記一次Mysql不走日期字段索引的原因小結(jié)

    記一次Mysql不走日期字段索引的原因小結(jié)

    本文主要介紹了記一次Mysql不走日期字段索引的原因,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • Mysql刪除重復(fù)數(shù)據(jù)通用SQL的兩種方法

    Mysql刪除重復(fù)數(shù)據(jù)通用SQL的兩種方法

    本文主要介紹了Mysql刪除重復(fù)數(shù)據(jù)通用SQL的兩種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • 簡(jiǎn)單談?wù)刴ysql左連接內(nèi)連接

    簡(jiǎn)單談?wù)刴ysql左連接內(nèi)連接

    這篇文章主要給大家介紹了關(guān)于mysql左連接內(nèi)連接的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • mysql 存儲(chǔ)過(guò)程的問(wèn)題

    mysql 存儲(chǔ)過(guò)程的問(wèn)題

    最近我接觸了一本php 與 mysql,老外寫(xiě)的一本書(shū),書(shū)中有個(gè)tshirtshop網(wǎng)店代碼,其中操作數(shù)據(jù)庫(kù)的大多用的是mysql存儲(chǔ)過(guò)程
    2009-06-06
  • 深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

    深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵

    這篇文章主要介紹了深入分析mysql為什么不推薦使用uuid或者雪花id作為主鍵,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09

最新評(píng)論