Mysql之count(*),count(1)與count(column)區別
資料庫查詢相信很多人都不陌生,所有經常有人調侃程式設計師就是CRUD專員,這所謂的CRUD指的就是資料庫的增刪改查。在資料庫的增刪改查操作中,使用最頻繁的就是查詢操作。而在所有查詢操作中,統計數量操作更是經常被用到。關於資料庫中行數統計,無論是MySQL還是Oracle,都有一個函式可以使用,那就是COUNT。但是,就是這個常用的COUNT函式,卻暗藏著很多玄機,尤其是在面試的時候,一不小心就會被虐。不信的話請嘗試回答下以下問題:
- 1、COUNT有幾種用法?
- 2、COUNT(欄位名)和COUNT(*)的查詢結果有什麼不同?
- 3、COUNT(1)和COUNT(*)之間有什麼不同?
- 4、COUNT(1)和COUNT(*)之間的效率哪個更高?
- 5、為什麼《阿里巴巴Java開發手冊》建議使用COUNT(*)
- 6、MySQL的MyISAM引擎對COUNT(*)做了哪些優化?
- 7、MySQL的InnoDB引擎對COUNT(*)做了哪些優化?
- 8、上面提到的MySQL對COUNT(*)做的優化,有一個關鍵的前提是什麼?
- 9、SELECT COUNT(*) 的時候,加不加where條件有差別嗎?
- 10、COUNT(*)、COUNT(1)和COUNT(欄位名)的執行過程是怎樣的?
以上10道題,如果您可以全部準確無誤的回答的話,那說明你真的很瞭解COUNT函數了,如果有哪些知識點是不瞭解的,那麼本文正好可以幫你答疑解惑。
1、認識COUNT
關於COUNT函式,在MySQL官網中有詳細介紹:
簡單翻譯一下:
1、COUNT(expr) ,返回SELECT語句檢索的行中expr的值不為NULL的數量。結果是一個BIGINT值。
2、如果查詢結果沒有命中任何記錄,則返回0
3、但是,值得注意的是,COUNT(*) 的統計結果中,會包含值為NULL的行數。
即以下表記錄
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)查詢結果如下:
select count(*),count(id),count(id2) from #bla results 7 3 2
除了COUNT(id)
和COUNT(*)
以外,還可以使用COUNT(常量)
(如COUNT(1)
)來統計行數,那麼這三條SQL語句有什麼區別呢?到底哪種效率更高呢?為什麼《阿里巴巴Java開發手冊》中強制要求不讓使用COUNT(列名)
或COUNT(常量)
來替代COUNT(*)
呢?
2、COUNT(列名)、COUNT(常量)和COUNT(*)之間的區別
前面我們提到過COUNT(expr)用於做行數統計,統計的是expr不為NULL的行數,那麼COUNT(列名)、 COUNT(常量) 和 COUNT(*)這三種語法中,expr分別是列名、 常量 和 *。那麼列名、 常量和 *這三個條件中,常量 是一個固定值,肯定不為NULL。*可以理解為查詢整行,所以肯定也不為NULL,那麼就只有列名的查詢結果有可能是NULL了。所以, COUNT(常量) 和 COUNT(*)表示的是直接查詢符合條件的資料庫表的行數。而COUNT(列名)表示的是查詢符合條件的列的值不為NULL的行數。除了查詢得到結果集有區別之外,COUNT(*)相比COUNT(常量) 和 COUNT(列名)來講,COUNT(*)是SQL92定義的標準統計行數的語法,因為他是標準語法,所以MySQL資料庫對他進行過很多優化。SQL92,是資料庫的一個ANSI/ISO標準。它定義了一種語言(SQL)以及資料庫的行為(事務、隔離級別等)。