共計 2750 個字符,預計需要花費 7 分鐘才能閱讀完成。
自動寫代碼機器人,免費開通
如何在 MySQL 中使用 count 聚合函數?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
一、基本使用
count 的基本作用是有兩個:
統計某個列的數據的數量;
統計結果集的行數;
用來獲取滿足條件的數據的數量。但是其中有一些與使用中印象不同的情況,比如當 count 作用一列、多列、以及使用 * 來表達整行產生的效果是不同的。
示例表如下:
CREATE TABLE `NewTable` (`id` int(11) NULL DEFAULT NULL ,
`name` varchar(30) NULL DEFAULT NULL ,
`country` varchar(50) NULL DEFAULT NULL ,
`province` varchar(30) NULL DEFAULT NULL ,
`city` varchar(30) NULL DEFAULT NULL
)ENGINE=InnoDB

1.1 不計算 NULL 的值
如果有 NULL 值,在返回的結果中會被過濾掉
select count(country) from person;
返回結果如下:

如果滿足條件的數據項不存在,則結構返回 0,經常通過這種方式判斷是否有滿足條件的數據存在;返回的數據類型是 bigint。
1.2 對 count(*)的處理
count(*)的處理是有點不同的,它會返回所有數據的數量,但是不會過濾其中的 NULL 值,它也并不是相當于展開成所有的列,而是直接會忽略所有的列而直接統計所有的行數。語句如下:
select count(*) from person;
返回結果如下:

當想要返回所有的數據的數量的時候,但是又不想包括全部是 NULL 的列,使用 count(*)是不可能做到的,但是在 1.1 中說到 count 作用于列的時候會過濾 NULL,那么直接這么寫是不是對?
select count(id, `name`, country, province, city) from person;
那就錯了,count 只能作用于單列,不能作用于多列,所以上面的寫法是錯誤的。
另外針對 count(*)語句,在 MyISAM 存儲引擎中做了優化,每個表的數據行數都會存儲在存儲引擎中,可以很快拿到;但是在事務性的存儲引擎中,比如 InnoDB 中,因為會涉及到多個事務;
1.3 對 count(distinct …)的處理
count(distinct …)會返回彼此不同但是非 NULL 的數據的行數。這一點和只使用 distinct 是有區別的,因為 distinct 是不過濾 NULL 值的,詳見 MySQL 中 distinct 的使用方法。
– 如果沒有符合條件的數據則返回 0;
– 該語句可以作用于多列,是當各個列之間有一個不同,就認為整行數據不同,與 distinct 作用于多列時效果相同;
select count(DISTINCT country) from person;
返回結果如下:

但是對于 count(*)和 count(distinct)兩者的結合,如下:
select count(DISTINCT *) from person;
該語句是錯誤的,無法執行,因此與 select count(DISTINCT *) from person 還是有區別的。
二、性能優化
通常情況下,count(*)操作需要大量掃描數據表中的行,如果避免掃描大量的數據就成為優化該語句的關鍵所在。針對這個問題可以從如下兩個角度考慮。
2.1 在數據庫的層次上優化
2.1.1 針對 count(*)
在 MySQL 內部已經針對 count(*)進行了優化,使用 explain 查詢如下:
EXPLAIN select count(*) from person;

從中可以看出該查詢沒有使用全表掃描也沒有使用索引,甚至不需要查詢數據表,在上面的示例數據庫中得知,該庫的存儲引擎是 InnoDB,而且其中既沒有主鍵也沒有索引。
2.2 針對單個列進行 count
查詢如下:
EXPLAIN select count(country) from person where id

發現在沒有主鍵和索引的情況下,對全表進行了掃描。在數據中避免大量掃描數據行,一個最直接的方法使用索引:
當對 id 設置為一般索引:INDEX abc (id) USING BTREE。
執行查詢如下:
EXPLAIN select count(country) from person where id
結果如下:

此時發現并沒有使用索引,仍然進行的是全表掃描,當執行如下時:
EXPLAIN select count(country) from person where id
結果如下:

這是使用了索引進行了范圍查詢,顯然比上面的要好。
但是問題來了,為什么有時候使用索引,有時候不用索引?在上面的第一次查詢中已經能夠檢測出可能的 key 但是并沒有使用?如果有知道的大神給解讀一下!
對 id 設置為主鍵,執行查詢如下:
EXPLAIN select count(country) from person where id
結果如下:

2.2 在應用的層次上優化
在應用的層次上優化,可以考慮在系統架構中引入緩存子系統,比如在過去中常用的 Memcached,或者現在非常流行的 Redis,但是這樣會增加系統的復雜性。
mysql group by 與聚合函數 (sum,count 等) 實例
首先我們先來了解一下 mysql 聚合函數
mysql 中一種特殊的函數: 聚合函數,SUM, COUNT, MAX, MIN, AVG 等。這些函數和其它函數的根本區別就是它們一般作用在多條記錄上。例如:
SELECT SUM(score) FROM table
這個 sql 的意思是查詢表 table 里面所有 score 列的總和。
接著我們通過一個實例來講解 group by 語句中如何使用聚合函數。
book 表如下:
idfirst_namelast_namecity1JasonMartinToronto2AlisonMathewsVancouver3JamesMathewsVancouver4CeliaRiceVancouver5DavidLarryNew York
現在我們要對 city 進行分組查詢,并獲取每個分組有多少條數據,我們需要 count 聚合函數。
SELECT *,count(*) FROM book GROUP BY city
結果為:
idfirst_namelast_namecitycount(*)1JasonMartinToronto12AlisonMathewsVancouver35DavidLarryNew York1
看完上述內容,你們掌握如何在 MySQL 中使用 count 聚合函數的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注丸趣 TV 行業資訊頻道,感謝各位的閱讀!
向 AI 問一下細節