關於數據庫優化1——關於count(1),count(*),和count(列名)的區別,和關於表中字段順序的問題


1.關於count(1),count(*),和count(列名)的區別

  相信大家總是在工作中,或者是學習中對於count()的到底怎么用更快。一直有很大的疑問,有的人說count(*)更快,也有的人說count(列名)更快,那到底是誰更快,我將會在本文中詳細介紹一下到底是count(1),count(*)和count(列明)的區別,和更適合的使用場景。   

  往常在工作中有人會說count(1)比count(*)會快,或者相反,首先這個結論肯定是錯的,實際上count(1)和count(*)並沒有區別

  接下來,我們來對比一下count(*)和count(列)到底誰更快一些

  首先我們執行以下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的執行計划

  

  

  通過我們建完索引后。突然發現count(列)變快了好多,但是count(*)還是和以前一樣的。這說明了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 /

  接下來我們在來看一下count(*)的執行計划

  

  現在count(*)和count(列)一樣快了,由此我們得出了這個結論:count(列)和count(*)其實一樣快,如果索引列是非空的,count(*)可用到索引,此時一樣快。

  總結:但是真的結論是這樣的么。其實不然。其實在數據庫中count(*)和count(列)根本就是不等價的,count(*)是針對於全表的而count(列)是針對於某一列的,如果此列值為空的話,count(列)是不會統計這一行的。所以兩者根本沒有可比性,性能比較首先要考慮寫法等價,這兩個語句根本就不等價。也就失去了去比較的意義!!!


2.關於表中字段順序的問題

  首先我們建一張有25個字段的表並加入數據在進行count(*)和count(列)比較。由於建表語句和插入語句和上面雷同。就不貼出代碼了。

       然后我們分別執行count(*)和count每一列的操作來看一下到底誰更快一些,由於執行計划太多,就不一一貼圖了。我整理了一個excel來給大家看一下執行的結果

  

  經過實驗我們看出,count(列)越往后。我們的執行效率越慢。所以,我們得出以下結論:

        1.列的偏移量決定性能,列越靠后,訪問的開銷越大

      2.由於count(*)的算法與列偏移量無關,所以count(*)最快。

  總結:所以我們在開發設計中。越常用的列,要放在靠前的位置。而cout(*)和count(列)是兩個不等價的用法,所以無法比較哪個性能更好,在實際的sql優化場景中要根據當時的業務場景再去考慮是使用count(*)還是count(列)(其中的區別上文有提到)。

  

  

 

  

  

  

 

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM