性能对比:Count(字段)、Count(主键)、Count(1)、Count(*)
本文經授權轉載自微信公眾號:猿人谷
最近有幾個小伙伴留言說不清楚Count(字段)、Count(主鍵)、Count(1)、Count(*)的區別,特此寫篇短文說明下。
以下討論是基于InnoDB引擎。
至于分析性能差別的時候,可以記住以下幾個原則:
server層要什么就給什么;
InnoDB只給必要的值
現在的優化器只優化了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才累加。也就是前面的第一條原則,server層要什么字段,InnoDB就返回什么字段。
但是count(*)是例外,并不會把全部字段取出來,而是專門做了優化,不取值。count(*)肯定不是null,按行累加。
看到這里,你一定會說,優化器就不能自己判斷一下嗎,主鍵id肯定非空啊,為什么不能按照count(*)來處理,多么簡單的優化啊。
當然,mysql專門針對這個語句進行優化,也不是不可以。但是這種需要專門優化的情況太多了,而且mysql已經優化過count(*)了,直接使用這種用法就可以了。
所以結論是:按照效率排序的話,count(字段) < count(主鍵id) < count(1) ≈ count(*)。所以建議盡量使用count(*)。
有道無術,術可成;有術無道,止于術
歡迎大家關注Java之道公眾號
好文章,我在看??
總結
以上是生活随笔為你收集整理的性能对比:Count(字段)、Count(主键)、Count(1)、Count(*)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库设计漫谈之一
- 下一篇: 一致性哈希的分析与实现