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

2021-08-02 23:27:18 字數 2788 閱讀 5606

本文的環境是windows 10,mysql版本是5.7.12-log

count的基本作用是有兩個:

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

示例表如下:

如果有null值,在返回的結果中會被過濾掉

select

count(country) from person;

返回結果如下:

如果滿足條件的資料項不存在,則結構返回0,經常通過這種方式判斷是否有滿足條件的資料存在;返回的資料型別是bigint

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中,因為會涉及到多個事務;

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.1 針對count(*)

在mysql內部已經針對count(*)進行了優化,使用explain查詢如下:

explain select

count(*) from person;

從中可以看出該查詢沒有使用全表掃瞄也沒有使用索引,甚至不需要查詢資料表,在上面的示例資料庫中得知,該庫的儲存引擎是innodb,而且其中既沒有主鍵也沒有索引。

2.2 針對單個列進行count

查詢如下:

explain select

count(country) from person where id > 2;

發現在沒有主鍵和索引的情況下,對全表進行了掃瞄。在資料中避免大量掃瞄資料行,乙個最直接的方法使用索引:

在應用的層次上優化,可以考慮在系統架構中引入快取子系統,比如在過去中常用的memcached,或者現在非常流行的redis, 但是這樣會增加系統的複雜性。

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

count的基本作用是有兩個 用來獲取滿足條件的資料的數量。但是其中有一些與使用中印象不同的情況,比如當count作用一列 多列 以及使用 來表達整行產生的效果是不同的。1 不計算null的值 select count province from counttest 結果 5 select coun...

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 代替...