SQL優化之count(*),count(列)


一、count各種用法的區別

1、count函數是日常工作中最常用的函數之一,用來統計表中數據的總數,常用的有count(*),count(1),count(列)。count(*)和count(1)是用來統計表中共有多少數據。是針對全表的

1 SELECT COUNT(*) FROM TAB1;
2 SELECT COUNT(1) FROM TAB1;
3 SELECT COUNT(*) FROM TAB1, TAB2;     #顯示兩表做笛卡爾積后的行數

 2、count(列)是針對於某一列的,如果此列值為空的話,count(列)是不會統計這一行的。NULL不會算在行數統計之內

1 CREATE TABLE T1(I int);
2 INSERT INTO T1 VALUES(1),(2),(NULL);
3 SELECT COUNT(*) FROM T1;              # 結果為3
4 SELECT COUNT(*) FROM T1;              # 結果為2

 二、關於count的用法,誰更快

1、由上文可知,在數據庫中count(*)和count(列)根本就是不等價的,count(*)是針對於全表的,而count(列)是針對於某一列的,如果此列值為空的話,count(列)是不會統計這一行的

所以兩者根本沒有可比性,性能比較首先要考慮寫法等價,這兩個語句根本就不等價的。也沒有比較的意義。

2、建一張有25個字段的表並加入數據在進行count(*)和count(列)比較,分別執行count(*)和count每一列的操作來看一下誰更快。結果如下:

結論:列的偏移量決定性能,列越靠后,訪問的開銷越大。由於count(*)的算法與列偏移量無關,所以count(*) 最快,count( 最后列) 最慢所以:在設計表結構的過程中,越常用到的            列,要放在表結構的前邊,不常用的列,放在表結構的后邊。在工作中根據實際業務再考慮應該使用count(*)還是count(列)

PS: conut(1)和count(*)是一樣的。但是在informix數據庫中,對count(*)做過算法優化,遠遠快於count(1)。

三、關於SQL優化的一些誤區

1、在聯合查詢中,和表的連接順序無關。有人認為數據庫的解析器是按順序掃描from字句中的表名。應該選擇小表作為基礎表優先掃描(ps:如果現在的小表隨着業務量的提升變成大表了,豈 不是要經常修改應用)。所以這種說法是不成立的,在聯合查詢中,以下的兩種寫法是沒有區別的

1 T1(2條數據)
2 T2(1萬條數據)
3 SELECT COUNT(*) FROM T1, T2;
4 SELECT COUNT(*) FROM T2, T1;

2、和where字句的連接順序也無關。數據庫在解析where字句時,也是按順序解析(oracle是自下而上)。有些人認為where子句中排在最后的表應該是返回數據量少的表。這種說法也是不成立的

1 如:從T1表查到的數據比較少或該表的條件比較確定。
2 SELECT * FROM T1,T2 WHRE T1.A > 10 AND T2.B = 20;
3 SELECT * FROM T1,T2 WHRE  T2.B = 20 AND T1.A > 10;
4 如果T2表返回數據量大,第二條SQL比第一條快(不成立)

3、用not exists取代not in是沒有依據的(在oracle11g中都是采用高效的anti反連接算法)

 


免責聲明!

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



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