日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

count(1),count(*),count(主键) 性能对比及辟谣

發(fā)布時(shí)間:2025/3/11 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 count(1),count(*),count(主键) 性能对比及辟谣 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

分享一波:程序員賺外快-必看的巔峰干貨

前言

前段時(shí)間關(guān)于統(tǒng)計(jì)數(shù)量的sql問(wèn)題和朋友進(jìn)行了討論,網(wǎng)上關(guān)于這三種查詢(xún)方式說(shuō)法不一,主要有以下兩種說(shuō)法。

count(*) = count(主鍵) > count(1) count(主鍵) > count(*) > count(1)

今天對(duì)這三種方式進(jìn)行探究。

數(shù)據(jù)庫(kù)為mysql 5.7.12,引擎為InnoDB。

建表

CREATE TABLE user (
id int(32) NOT NULL AUTO_INCREMENT,
name varchar(500) DEFAULT NULL COMMENT ‘姓名’,
deleted int(2) NOT NULL DEFAULT ‘1’ COMMENT ‘邏輯刪除’,
created_date datetime DEFAULT NULL COMMENT ‘創(chuàng)建時(shí)間’,
created_by varchar(255) DEFAULT NULL,
update_date datetime DEFAULT NULL,
update_by varchar(255) DEFAULT NULL,
version int(11) NOT NULL DEFAULT ‘1’ COMMENT ‘樂(lè)觀鎖’,
PRIMARY KEY (id) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1502726 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT=‘用戶表’;

循環(huán)插入150萬(wàn)條數(shù)據(jù)。

DROP PROCEDURE
IF
EXISTS proc_initData;
DELIMITER $
CREATE PROCEDURE proc_initData () BEGIN
DECLARE
i INT DEFAULT 1;
WHILE
i <= 5000000 DO
INSERT INTO user ( name, created_date, update_date )
VALUES
( ‘哈哈哈啊哈哈哈’, NOW(), NOW() );

SET i = i + 1;END WHILE;

END $ CALL proc_initData ();

這里需要使用到mysql的explain關(guān)鍵字,對(duì)count(1),count(*),count(id),count(name)分別查看性能

explain select count(1) from user
explain select count(*) from user
explain select count(id) from user
explain select count(name) from user

可以看出,select count(1)、count(*)、count(id)的執(zhí)行計(jì)劃是一毛一樣的。多次執(zhí)行取平均值,三者的性能也是非常趨近,因此可以認(rèn)為三者性能相同。這里我加了個(gè)count(name)進(jìn)行對(duì)比,并將最后30萬(wàn)條數(shù)據(jù)的name置空,可以看出性能有明顯的差別。

mysql底層對(duì)count查詢(xún)做了優(yōu)化,當(dāng)mysql確定count中的列名不為空時(shí),實(shí)際上就是在統(tǒng)計(jì)行數(shù)。那么mysql內(nèi)部會(huì)將count(列名)優(yōu)化為count(*) —— 出自《高性能MySQL》一書(shū)

也就是說(shuō)count(1)和count(主鍵字段)還是要優(yōu)化到count()的,而如果只是統(tǒng)計(jì)某個(gè)列,只要該列不為空,無(wú)論是否為索引,都會(huì)被優(yōu)化為count(),因此三者性能并無(wú)任何差異。官方文檔對(duì)其也進(jìn)行了解釋。

InnoDB handles SELECT COUNT(*) and SELECT COUNT(1) operations in the same way. There is no performance difference.

https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_count

至此,事實(shí)上并未解決關(guān)于這個(gè)問(wèn)題的疑惑。上面的內(nèi)容都在強(qiáng)調(diào)“Mysql”,就是說(shuō),上面的驗(yàn)證可能僅對(duì)MySql有效,其他的數(shù)據(jù)庫(kù)可能未必會(huì)對(duì)count語(yǔ)句進(jìn)行優(yōu)化。因此我又通過(guò)SQLServer去驗(yàn)證。

因?yàn)槲冶镜夭](méi)有安裝SQLServer,因此我是直接使用公司的開(kāi)發(fā)庫(kù)進(jìn)行驗(yàn)證,這里不方便截圖,直接說(shuō)明一下200萬(wàn)條數(shù)據(jù)驗(yàn)證結(jié)果。

列名為主鍵,count(列名)會(huì)比count(1)快 列名不為主鍵,count(1)會(huì)比count(列名)快 如果表多個(gè)列并且沒(méi)有主鍵,則 count(1) 的執(zhí)行效率優(yōu)于 count(*) 如果有主鍵,則 select count(主鍵)的執(zhí)行效率是最優(yōu)的 如果表只有一個(gè)字段,則 select count(*)最優(yōu)。

可見(jiàn),在SQLServer中,count(*)的性能并沒(méi)有count(主鍵)高。
結(jié)語(yǔ)

根據(jù)上面對(duì)兩個(gè)數(shù)據(jù)庫(kù)的驗(yàn)證得出結(jié)論:不說(shuō)是什么數(shù)據(jù)庫(kù)都是耍流氓!SQL標(biāo)準(zhǔn)只提供了count這個(gè)內(nèi)置函數(shù),所有的數(shù)據(jù)庫(kù)需要遵循這個(gè)標(biāo)準(zhǔn),但是不同的數(shù)據(jù)庫(kù)對(duì)于count的處理不同。在mysql中建議寫(xiě)count(*),而在SQLServer中建議寫(xiě)count(主鍵),在PostgreSql以及其他數(shù)據(jù)庫(kù)中并未對(duì)其進(jìn)行驗(yàn)證

分享一波:程序員賺外快-必看的巔峰干貨

如果以上內(nèi)容對(duì)你覺(jué)得有用,并想獲取更多的賺錢(qián)方式和免費(fèi)的技術(shù)教程

請(qǐng)關(guān)注微信公眾號(hào):HB荷包

一個(gè)能讓你學(xué)習(xí)技術(shù)和賺錢(qián)方法的公眾號(hào),持續(xù)更新

總結(jié)

以上是生活随笔為你收集整理的count(1),count(*),count(主键) 性能对比及辟谣的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。