偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

select count(?) from t之間的性能差別是什么

開發(fā) 前端
今天我們就來(lái)聊聊這幾種不同的統(tǒng)計(jì)方式是怎么實(shí)現(xiàn)的,他們之間的性能差別是什么。

[[402107]]

在開發(fā)中,我們一定經(jīng)常遇到需要統(tǒng)計(jì)表總記錄的時(shí)候,在 select count(?) from t 這樣的查詢語(yǔ)句里面,count(*)、count(主鍵 id)、count(字段) 和 count(1) 該怎么選擇呢?

阿里巴巴開發(fā)規(guī)約其中MySQL規(guī)約中,有4條都在規(guī)范count的用法,我們查看其中的一條:

【強(qiáng)制】不要使用count(列名)或count(常量)來(lái)替代count(*), count(*)就是SQL92定義的標(biāo)準(zhǔn)統(tǒng)計(jì)行數(shù)的語(yǔ)法,跟數(shù)據(jù)庫(kù)無(wú)關(guān),跟NULL和非NULL無(wú)關(guān)。

說(shuō)明:count(*)會(huì)統(tǒng)計(jì)值為NULL的行,而count(列名)不會(huì)統(tǒng)計(jì)此列為NULL值的行。

那么今天我們就來(lái)聊聊這幾種不同的統(tǒng)計(jì)方式是怎么實(shí)現(xiàn)的,他們之間的性能差別是什么。

count()函數(shù)

首先我們需要了解count() 的語(yǔ)義。

count()是一個(gè)聚合函數(shù),對(duì)于返回的結(jié)果集,一行行的判斷,如果count函數(shù)的參數(shù)不是null,累計(jì)值就加1,否則不加。最后返回累計(jì)值。如果沒有則返回0。

count(*)、count(主鍵 id) 和 count(1) 都表示返回滿足條件的結(jié)果集的總行數(shù);而 count(字段),則表示返回滿足條件的數(shù)據(jù)行里面,參數(shù)“字段”不為null的總個(gè)數(shù)。

接下來(lái)我們具體分析每種統(tǒng)計(jì)方式的性能差別。

count(*)

我們?cè)诜治鲆粭lSQL語(yǔ)句的實(shí)現(xiàn)時(shí),一定不能脫離存儲(chǔ)引擎,在不同的MySQL存儲(chǔ)引擎中,count(*)有不同的實(shí)現(xiàn)。

  • MyISAM引擎把一個(gè)表的總行數(shù)存在了磁盤上,所以在執(zhí)行count(*)的時(shí)候直接返回磁盤上的這個(gè)數(shù)就可以,效率很高。
  • InnoDB引擎是需要一行一行地從引擎中讀出數(shù)據(jù)然后累計(jì)計(jì)數(shù)。

這個(gè)時(shí)候你是不是在想,MySQL建表時(shí)的存儲(chǔ)引擎已經(jīng)默認(rèn)為InnoDB了,而且很多MySQL相關(guān)的書籍中也提到不是特別場(chǎng)景的必要,就使用InnoDB。

但是我們?cè)谑褂胏ount(*)做統(tǒng)計(jì)的時(shí)候隨著表記錄的增加效率會(huì)越來(lái)越慢,InnoDB怎么就不能跟MyISAM一樣也把總記錄數(shù)提前存儲(chǔ)起來(lái)呢?

這里主要的一個(gè)原因是InnoDB是支持事務(wù)的,由于MVCC的原因,InnoDB表在某個(gè)時(shí)刻應(yīng)該返回多少行是不確定的,它必須根據(jù)當(dāng)前的事務(wù)隔離級(jí)別判斷某一個(gè)記錄對(duì)于當(dāng)前事務(wù)是否可見。

雖然InnoDB是需要一行一行的統(tǒng)計(jì),但是MySQL也是做了優(yōu)化的。通過(guò)前面索引文章介紹的知識(shí)我們了解到,InnoDB分為主鍵索引樹和普通索引樹,普通索引樹的葉子節(jié)點(diǎn)是主鍵值而不是行記錄。所以,普通索引樹要比主鍵索引樹小很多,所以count(*)在遍歷索引樹的時(shí)候會(huì)找最小的那棵樹來(lái)遍歷。

在保證邏輯正確的前提下,盡量減少掃描的數(shù)據(jù)量,是數(shù)據(jù)庫(kù)系統(tǒng)設(shè)計(jì)的通用法則之一。

count(*)也并不會(huì)把全部字段取出來(lái),而是做了優(yōu)化,不取值。

count(*)的參數(shù)肯定不是null,按行累加之后返回結(jié)果。

count(主鍵 id)

count(主鍵 id) ,InnoDB引擎會(huì)遍歷整張表,把每一行的id值取出來(lái),傳給server層。server層拿到引擎給的id值后,判斷是不可能為空的,就按行累加。

count(1)

count(1),InnoDB引擎遍歷整張表,但是不取值。server層對(duì)于返回的每一行存放一個(gè)數(shù)字1,判斷是不可能為空過(guò)的,按行累加。

count(字段)

而對(duì)于count(字段)字段來(lái)說(shuō),我們需要分兩種情況分析參數(shù)字段。

如果這個(gè)參數(shù)字段是不允許為null(not null)的,那么InnoDB引擎則一行行地從記錄里面讀取這個(gè)字段,判斷不能為null,則按行累加。

如果這個(gè)參數(shù)字段是允許為null的,那么執(zhí)行的時(shí)候,判斷到可能是null的時(shí)候還要把值取出來(lái)再判斷一次,不是null才累加。

小結(jié)

count(字段)和count(主鍵 id)因?yàn)樾枰獜囊嬷蟹祷刂担瑫?huì)涉及到解析數(shù)據(jù)行以及拷貝字段的操作,性能上差于其他兩種。

而count(字段)還需要判斷字段參數(shù)是否為null,多了判斷的操作,性能上會(huì)差于count(主鍵 id)。

count(1)和count(*)都不會(huì)涉及到取值,性能上差別不大。

所以結(jié)論就是,按照查詢效率排名結(jié)果如下:

count(字段)<count(主鍵 id)<count(1)≈count(*)。

按照開發(fā)規(guī)范,建議盡量使用count(*)。

我是勾勾,認(rèn)真生活,快樂工作!愿你每天開心!

 

責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2018-05-21 21:26:59

Apache HiveHbaseSQL

2022-11-18 16:10:03

云計(jì)算虛擬機(jī)

2017-03-01 21:15:44

AI機(jī)器學(xué)習(xí)深度學(xué)習(xí)

2023-02-24 08:03:24

ChatGPT人臉識(shí)別分支

2019-03-19 19:49:04

負(fù)載均衡硬件軟件

2022-11-15 10:03:34

2023-10-23 11:07:37

HTTPRPC

2023-06-09 09:10:06

nftablesiptables

2022-09-19 15:57:36

JVM對(duì)象緩存

2019-06-12 09:50:23

selectMySQLSQL

2020-09-06 22:04:48

Python運(yùn)算符開發(fā)

2025-02-06 08:44:11

MySQLEXISTSIN

2024-12-30 07:20:00

Redis數(shù)據(jù)庫(kù)MySQL

2016-03-21 10:40:53

RDDSpark SQL數(shù)據(jù)集

2021-03-15 14:00:56

PythonC語(yǔ)言編程語(yǔ)言

2021-09-01 09:19:03

人工智能機(jī)器學(xué)習(xí)數(shù)據(jù)分析

2021-10-27 10:12:54

DockerContainerdRunC

2015-02-26 10:29:41

Google百度

2021-05-06 15:08:40

開發(fā)前端后端

2022-07-06 06:17:51

PandasScipynumpy
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)