自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

淺聊 count(1)、count(*) 與 count(列名) 的區(qū)別

數(shù)據(jù)庫
COUNT(1) 和 COUNT(*) 表示的是直接查詢符合條件的數(shù)據(jù)庫表的行數(shù)。而 COUNT(列名) 表示的是查詢符合條件的列的值不為 NULL 的行數(shù)。

簡單來說:

COUNT(1) 和 COUNT(*) 表示的是直接查詢符合條件的數(shù)據(jù)庫表的行數(shù)。而 COUNT(列名) 表示的是查詢符合條件的列的值不為 NULL 的行數(shù)。

除了查詢得到結(jié)果集有區(qū)別之外,在性能方面 COUNT() 約等于 COUNT(1),但是 COUNT() 是 SQL92 定義的標準統(tǒng)計行數(shù)的語法**。因為它是標準語法,所以 MySQL 數(shù)據(jù)庫對其進行了很多優(yōu)化。

COUNT

關(guān)于 COUNT 函數(shù),在 MySQL 官網(wǎng)中有詳細介紹:

COUNT(expr) 返回 SELECT 語句檢索的行中 expr 的值不為 NULL 的數(shù)量。結(jié)果是一個 BIGINT 值。

如果查詢結(jié)果沒有命中任何記錄,則返回 0。

但是,值得注意的是,COUNT(*) 的統(tǒng)計結(jié)果中會包含值為 NULL 的行數(shù)。

即以下表記錄:

create table #bla(id int,id2 int)
insert #bla values(null,null)
insert #bla values(1,null)
insert #bla values(null,1)
insert #bla values(1,null)
insert #bla values(null,1)
insert #bla values(1,null)
insert #bla values(null,null)

使用語句 count(*),count(id),count(id2)查詢結(jié)果如下:

select count(*),count(id),count(id2)
from #bla
results 7 3 2

COUNT(*)的優(yōu)化

COUNT(*) 在 MySQL 中的優(yōu)化與所使用的執(zhí)行引擎密切相關(guān),常見的執(zhí)行引擎包括 MyISAM 和 InnoDB。

MyISAM 和 InnoDB 之間有許多區(qū)別,其中一個關(guān)鍵區(qū)別與接下來要討論的 COUNT(*) 有關(guān):MyISAM 不支持事務(wù),其鎖定級別為表級鎖;而 InnoDB 支持事務(wù),并且使用行級鎖。

由于 MyISAM 的表級鎖,同一表上的操作需要串行進行。因此,MyISAM 做了一個簡單的優(yōu)化,即單獨記錄表的總行數(shù)。對于不帶 WHERE 條件的 COUNT(*) 查詢,可以直接返回這個記錄的值。

MyISAM 之所以能夠記錄表中的總行數(shù)并供 COUNT(*) 查詢使用,是因為其表級鎖機制保證了行數(shù)查詢的準確性,沒有并發(fā)的行數(shù)修改。

然而,對于 InnoDB,這種緩存操作就不可行了,因為 InnoDB 支持事務(wù),其中大部分操作使用行級鎖,可能導(dǎo)致表的行數(shù)被并發(fā)修改,從而使緩存的行數(shù)不準確。

盡管如此,InnoDB 也對 COUNT(*) 語句進行了一些優(yōu)化。

從 MySQL 8.0.13 開始,針對 InnoDB 的 SELECT COUNT(*) FROM tbl_name 查詢,在掃表過程中進行了優(yōu)化,前提是查詢語句不包含 WHERE 或 GROUP BY 等條件。

由于 COUNT(*) 只是為了統(tǒng)計總行數(shù),不關(guān)心具體值,因此,在掃表過程中選擇成本較低的索引可以節(jié)省時間。

InnoDB 中的索引分為聚簇索引(主鍵索引)和非聚簇索引(非主鍵索引)。非聚簇索引相比聚簇索引更小,因此 MySQL 會優(yōu)先選擇最小的非聚簇索引來掃表。

因此,在建表時,除了主鍵索引外,創(chuàng)建一個非主鍵索引也是有必要的。

這些優(yōu)化的前提是查詢語句中不包含 WHERE 和 GROUP BY 條件。

COUNT(*)和 COUNT(1)

MySQL 官方文檔對于 COUNT(*)和 COUNT(1) 的性能差異沒有做出具體說明。不過,可以從一些實踐和理論上推斷一些情況。

有些人認為COUNT(*) 在執(zhí)行時會轉(zhuǎn)換成 COUNT(1),因此 COUNT(1) 少了轉(zhuǎn)換步驟,所以更快。這個說法在某些情況下可能是正確的,因為 COUNT(*) 會返回表中所有行的數(shù)目,而 COUNT(1) 只需要計算行數(shù)而不需要檢查列值。

另一方面,也有人認為 MySQL 針對 COUNT(*) 做了特殊優(yōu)化,因此 COUNT(*) 更快。這個說法也是有一定道理的,因為 COUNT(*) 是 SQL92 定義的標準語法,MySQL 可能對其進行了一些優(yōu)化。

綜上所述,對于 COUNT(*) 和 COUNT(1) 的性能差異,可能取決于具體的情況和 MySQL 的版本。在實際情況中,可以根據(jù)具體的需求和環(huán)境選擇合適的寫法。

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

畫重點:same way, no performance difference。所以,對于 COUNT(1) 和 COUNT(*),MySQL 的優(yōu)化是完全一樣的,根本不存在誰比誰快!

那既然COUNT(*) 和 COUNT(1)一樣,建議用哪個呢?

建議使用 COUNT(*)!因為這個是 SQL92 定義的標準統(tǒng)計行數(shù)的語法,而且本文只是基于 MySQL 做了分析,關(guān)于 Oracle 中的這個問題,也是眾說紛紜的呢。

COUNT(字段)

最后,就是我們一直還沒提到的 COUNT(字段),他的查詢就比較簡單粗暴了,就是進行全表掃描,然后判斷指定字段的值是不是為 NULL,不為 NULL 則累加。

相比 COUNT(*),COUNT(字段) 多了一個步驟就是判斷所查詢的字段是否為 NULL,所以他的性能要比 COUNT(*) 慢。

責任編輯:趙寧寧 來源: 碼上遇見你
相關(guān)推薦

2021-12-16 11:41:19

MySQL 數(shù)據(jù)InnoDB

2024-11-15 09:29:12

2022-03-31 16:47:30

mysqlcount面試官

2019-07-05 16:26:06

MySQLcount(1)count(*)

2022-11-17 00:04:38

接口性能查詢

2022-06-30 08:01:53

mysqlmyisamcount

2022-05-09 08:01:23

countdistinctMySQL

2022-01-05 21:39:28

數(shù)據(jù)參數(shù)原理

2010-05-12 12:36:46

MySQL innod

2022-07-27 14:24:38

MySQL數(shù)據(jù)庫SQL

2021-05-19 07:35:00

MySQL數(shù)據(jù)庫COUNT

2010-09-10 13:45:18

SQLCOUNT()函數(shù)

2010-11-22 13:23:52

MySQL數(shù)據(jù)庫優(yōu)化

2021-07-13 07:52:03

SQL面試COUNT(*)

2009-11-25 10:15:48

PHP函數(shù)count(

2020-12-03 09:05:38

SQL代碼方案

2019-06-12 09:50:23

selectMySQLSQL

2024-04-29 07:38:09

SQLCOUNT檢索法

2010-09-10 13:30:49

SQLCOUNT(*)函數(shù)

2021-05-28 07:40:08

selectcount(?)from t
點贊
收藏

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