本文的環境是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 代替...