相信你們老是在工做中,或者是學習中對於count()的到底怎麼用更快。一直有很大的疑問,有的人說count(*)更快,也有的人說count(列名)更快,那究竟是誰更快,我將會在本文中詳細介紹一下究竟是count(1),count(*)和count(列明)的區別,和更適合的使用場景。 html
往常在工做中有人會說count(1)比count(*)會快,或者相反,首先這個結論確定是錯的,實際上count(1)和count(*)並無區別。算法
接下來,咱們來對比一下count(*)和count(列)到底誰更快一些sql
首先咱們執行如下sql,來看一下執行效率(下面sql針對的是ORACLE數據庫,大體邏輯爲先刪除t別,而後在根據dba_objects建立t表,在更新t表根據rownum)數據庫
1 drop table t purge; 2 create table t as select * from dba_objects; 3 --alter table T modify object_id null; 4 update t set object_id =rownum ; 5 set timing on 6 set linesize 1000 7 set autotrace on --開啓跟蹤 8 9 select count(*) from t; 10 / 11 select count(object_id) from t; 12 /
而後我們分別看一下「select count(*) from t」和「select count(object_id) from t」語句的執行計劃。(執行計劃是指sql的一個執行順序和耗費的資源,耗費的資源越少越快,若是在plsql中,使用F8能夠查看sql的執行計劃)性能
經過咱們執行sql的實驗來講,count(*)和count(列)消耗的資源是同樣的,說面他們是同樣快的,可是真的是這樣麼。那麼我們接着如下的實驗。學習
此次我們給object_id這一列加一個索引試一下。咱們執行一下索引sql優化
1 create index idx_object_id on t(object_id); 2 select count(*) from t; 3 / 4 5 6 select count(object_id) from t; 7 /
而後咱們在分別看一下兩條sql的執行計劃spa
經過咱們建完索引後。忽然發現count(列)變快了好多,可是count(*)仍是和之前同樣的。這說明了count(列)能夠用到索引,而count(*)不行,可是真的這樣麼,我們在往下看。設計
接下來咱們給object_id這個字段加上不可爲空條件。咱們執行如下sqlexcel
1 create index idx_object_id on t(object_id); 2 select count(*) from t; 3 / 4 5 6 select count(object_id) from t; 7 /
接下來咱們在來看一下count(*)的執行計劃
如今count(*)和count(列)同樣快了,由此咱們得出了這個結論:count(列)和count(*)其實同樣快,若是索引列是非空的,count(*)可用到索引,此時同樣快。
總結:可是真的結論是這樣的麼。其實否則。其實在數據庫中count(*)和count(列)根本就是不等價的,count(*)是針對於全表的,而count(列)是針對於某一列的,若是此列值爲空的話,count(列)是不會統計這一行的。因此二者根本沒有可比性,性能比較首先要考慮寫法等價,這兩個語句根本就不等價。也就失去了去比較的意義!!!
首先咱們建一張有25個字段的表並加入數據在進行count(*)和count(列)比較。因爲建表語句和插入語句和上面雷同。就不貼出代碼了。
而後咱們分別執行count(*)和count每一列的操做來看一下到底誰更快一些,因爲執行計劃太多,就不一一貼圖了。我整理了一個excel來給你們看一下執行的結果
通過實驗咱們看出,count(列)越日後。咱們的執行效率越慢。因此,咱們得出如下結論:
1.列的偏移量決定性能,列越靠後,訪問的開銷越大。
2.因爲count(*)的算法與列偏移量無關,因此count(*)最快。
總結:因此咱們在開發設計中。越經常使用的列,要放在靠前的位置。而cout(*)和count(列)是兩個不等價的用法,因此沒法比較哪一個性能更好,在實際的sql優化場景中要根據當時的業務場景再去考慮是使用count(*)仍是count(列)(其中的區別上文有提到)。
如下內容來自我的總結:
1.數據庫中只有一個字段:count(*)快
2.數據庫中有索引: