溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

MySQL中count(*)與count(1)哪個(gè)更快

發(fā)布時(shí)間:2020-11-30 15:15:59 來(lái)源:億速云 閱讀:415 作者:Leah 欄目:開發(fā)技術(shù)

MySQL中count(*)與count(1)哪個(gè)更快?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

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;

MySQL中count(*)與count(1)哪個(gè)更快

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

MySQL中count(*)與count(1)哪個(gè)更快

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

MySQL中count(*)與count(1)哪個(gè)更快

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

MySQL中count(*)與count(1)哪個(gè)更快

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

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

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

MySQL中count(*)與count(1)哪個(gè)更快

MySQL中count(*)與count(1)哪個(gè)更快

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

MySQL中count(*)與count(1)哪個(gè)更快

MySQL中count(*)與count(1)哪個(gè)更快

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

MySQL中count(*)與count(1)哪個(gè)更快

MySQL中count(*)與count(1)哪個(gè)更快

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

MySQL中count(*)與count(1)哪個(gè)更快

MySQL中count(*)與count(1)哪個(gè)更快

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

  1. count(*)被MySQL查詢優(yōu)化器改寫成了count(0),并選擇了idx_status索引

  2. count(1)和count(id)都選擇了idx_statux索引

  3. 加了force index(primary)之后,走了強(qiáng)制索引

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

為了驗(yàn)證count(*)會(huì)優(yōu)先選擇輔助索引樹這個(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;

MySQL中count(*)與count(1)哪個(gè)更快

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

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

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

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

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

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

關(guān)于MySQL中count(*)與count(1)哪個(gè)更快問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI