MySQL中聚合函式count的使用和效能優化

2021-10-03 22:27:35 字數 2413 閱讀 6376

count的基本作用是有兩個:

用來獲取滿足條件的資料的數量。但是其中有一些與使用中印象不同的情況,比如當count作用一列、多列、以及使用*來表達整行產生的效果是不同的。

1 不計算null的值

select count(province) from `counttest`;    結果:5

select count(name) from `counttest`;       結果:6

select count(*) from `counttest`;  結果:7

count(*)的處理是有點不同的,它會返回所有資料的數量,但是不會過濾其中的null值,它也並不是相當於展開成所有的列,而是直接會忽略所有的列而直接統計所有的行數

問題來了:想要返回所有的資料的數量的時候,但是又不想包括全部是null的列,

使用count(*)是不可能做到的,count作用於列的時候會過濾null,那麼直接這麼寫是不是對?

select count(id, `name`, country, province, city) from counttest;

那就錯了,count只能作用於單列,不能作用於多列 ,所以上面的寫法是錯誤的。

另外針對count(*)語句,在myisam儲存引擎中做了優化,每個表的資料行數都會儲存在儲存引擎中,可以很快拿到;但是在事務性的儲存引擎innodb中,因為會涉及到多個事務,不能直接拿到資料表的行數

例項:新建myisam 表:

- 區分(不同的count使用方式)

- count(主鍵 id)

- innodb 引擎會遍歷整張表,把每一行的 id 值都取出來,返回給 server 層。server 層拿到 id 後,判斷是不可能為空的,就按行累加。

- count(1)

-  innodb 引擎遍歷整張表,但不取值。server 層對於返回的每一行,放乙個數字「1」進去,判斷是不可能為空的,按行累加。

- count(1) 執行得要比 count(主鍵 id) 快。因為從引擎返回 id 會涉及到解析資料行,以及拷貝字段值的操作。

- count(字段)

- 如果這個「字段」是定義為 not null 的話,一行行地從記錄裡面讀出這個字段,判斷不能為 null,按行累加;

- 如果這個「字段」定義允許為 null,那麼執行的時候,判斷到有可能是 null,還要把值取出來再判斷一下,不是 null 才累加。 

-  但是 count(*) 是例外

-  並不會把全部字段取出來,而是專門做了優化,不取值。count(*) 肯定不是 null,按行累加。

-所以結論是:按照效率排序的話,count(字段)解決 count 效能問題

- 快取記錄條數 (注意快取和資料庫的一致性問題)

- 資料庫記錄條數(型別彙總表,開啟事務,保證一致性問題)

- 使用 explain / show table status 等近似值(不準確)

MySQL中聚合函式count的使用和效能優化

本文的環境是windows 10,mysql版本是5.7.12 log count的基本作用是有兩個 用來獲取滿足條件的資料的數量。但是其中有一些與使用中印象不同的情況,比如當count作用一列 多列 以及使用 來表達整行產生的效果是不同的。示例表如下 如果有null值,在返回的結果中會被過濾掉 s...

MySQL之聚合函式count 的用法

在使用mysql資料庫查詢的時候,涉及到數量查詢,總是會使用count函式,一般有 count count 字段 count 1 count 主鍵id 這幾種用法,這些用法有什麼不同,原來沒有仔細思考過,今天偶然看到,在此記錄,希望自己在以後的開發中,能夠有所體會。count 是乙個聚合函式,對於返...

MySql中的count 函式

1.count 函式是用來統計表中記錄的乙個函式,返回匹配條件的行數。2.count 語法 1 count 包括所有列,返回表中的記錄數,相當於統計表的行數,在統計結果的時候,不會忽略列值為null的記錄。2 count 1 忽略所有列,1表示乙個固定值,也可以用count 2 count 3 代替...