免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
SQLSERVER 里SELECT COUNT(1) 和SELECT COUNT(*)哪個(gè)性能好?

SQLSERVER 里SELECT COUNT(1) 和SELECT COUNT(*)哪個(gè)性能好?

今天遇到某人在我以前寫的一篇文章里問到

如果統(tǒng)計(jì)信息沒來(lái)得及更新的話,那豈不是統(tǒng)計(jì)出來(lái)的數(shù)據(jù)時(shí)錯(cuò)誤的了

這篇文章的地址:SQLSERVER是怎麼通過索引和統(tǒng)計(jì)信息來(lái)找到目標(biāo)數(shù)據(jù)的(第三篇)

之前我以為SELECT COUNT(*)是根據(jù)統(tǒng)計(jì)信息來(lái)的,但是后來(lái)想了一下,這個(gè)肯定不是

那么SQLSERVER怎麼統(tǒng)計(jì)SELECT COUNT(*)的呢??

其實(shí)SQLSERVER也是使用掃描的方法

大家也可以先看一下:SQLSERVER中的ALLOCATION SCAN和RANGE SCAN

但是這里不討論是ALLOCATION SCAN還是RANGE SCAN,大家知道SQLSERVER使用的是掃描的方式就可以了


聚集索引表

SQL腳本如下:

View Code

看一下執(zhí)行計(jì)劃

(圖片一)

1 SET STATISTICS PROFILE ON2 GO3 SELECT COUNT(*) FROM [dbo].[ct1]

 

(圖片二) 

這里需要了解流聚合運(yùn)算符

 MSDN對(duì)于流聚合運(yùn)算符的解釋

(圖片三)

 

宋沄劍的文章里也有對(duì)流聚合運(yùn)算符的解釋

SQL Server中的執(zhí)行引擎入門

 

重點(diǎn)是理解:Stream Aggregate 運(yùn)算符按一列或多列對(duì)行分組,然后計(jì)算由查詢返回的一個(gè)或多個(gè)聚合表達(dá)式

Stream Aggregate 運(yùn)算符按一列對(duì)行分組,然后計(jì)算由查詢返回的一個(gè)聚合表達(dá)式

我們用下面兩個(gè)圖會(huì)清楚一些

 

(圖片四)

 

(圖片五)

SQLSERVER對(duì)表中的行分組進(jìn)行掃描,但是SQLSERVER以多少行為一組來(lái)進(jìn)行掃描呢??這個(gè)不得而知了

為什麼要使用流聚合?

大家一定會(huì)自然而然地想到分組統(tǒng)計(jì)提高性能,特別是表中數(shù)據(jù)量非常大的時(shí)候,分組統(tǒng)計(jì)特別有用

 

計(jì)算標(biāo)量運(yùn)算符只是把聚合的結(jié)果隱式轉(zhuǎn)換為int類型

 

大家知道ct1表只有兩列,但是SELECT COUNT(3) FROM [dbo].[ct1]也能夠返回表中的行數(shù)

1 SELECT COUNT(1) FROM [dbo].[ct1]
1 SELECT COUNT(3) FROM [dbo].[ct1]

(圖片六)

 就算用列名都是一樣的執(zhí)行計(jì)劃

1 SELECT COUNT(c1) FROM [dbo].[ct1]2 SELECT COUNT(c2) FROM [dbo].[ct1]

(圖片七)

 

SQLSERVER究竟以哪一列來(lái)進(jìn)行表的行數(shù)統(tǒng)計(jì)的呢??????

答案就在

Stream Aggregate 運(yùn)算符要求輸入的數(shù)據(jù)要按某列進(jìn)行排序,如果由于前面的 Sort 運(yùn)算符或已排序的索引查找或掃描導(dǎo)致數(shù)據(jù)尚未排序,

則優(yōu)化器將在此運(yùn)算符前面使用一個(gè) Sort 運(yùn)算符,使表的某列是有序排序的。

1 SELECT  COUNT(*)2 SELECT  count33 SELECT  count(c2)

(圖片八)

上面三個(gè)SQL語(yǔ)句都是按照聚集索引的第一個(gè)字段(ct1表中的c1列)來(lái)進(jìn)行統(tǒng)計(jì)的

因?yàn)榫奂饕牡谝粋€(gè)字段是根據(jù)建立聚集索引的時(shí)候的排序順序預(yù)先排好序

Stream Aggregate 運(yùn)算符要求輸入的數(shù)據(jù)要按某列進(jìn)行排序

所以無(wú)論是指定字段名、*還是數(shù)字,都是根據(jù)聚集索引的第一個(gè)字段來(lái)統(tǒng)計(jì)


堆表

SQL腳本如下:

View Code

 

(圖片九)

 

 (圖片十)

堆表這里使用的是ALLOCATION SCAN

因?yàn)榉峙漤?yè)面的時(shí)候是根據(jù)c1列的值從1~12進(jìn)行分配的

(圖片十一)

109頁(yè)面存放的c1值是1

120頁(yè)面存放的c1值是2

174頁(yè)面存放的c1值是3

193頁(yè)面存放的c1值是4

8316頁(yè)面存放的c1值是5

8340頁(yè)面存放的c1值是6

8351頁(yè)面存放的c1值是7

8353頁(yè)面存放的c1值是8

。

。

。

(圖片十二)

這里執(zhí)行計(jì)劃在流聚合之前并沒有進(jìn)行排序的原因:因?yàn)榻ū磉M(jìn)行頁(yè)面分配的時(shí)候已經(jīng)按照C1列的值進(jìn)行有序的頁(yè)面分配

所以當(dāng)ALLOCATION SCAN的時(shí)候,C1列已經(jīng)是有序的了

(圖片十三)

不明白的童鞋可以再看一下:SQLSERVER中的ALLOCATION SCAN和RANGE SCAN

為什麼SQLSERVER選擇統(tǒng)計(jì)C1列的值,因?yàn)镃1列的值是可以排序的,C2列不能排序,統(tǒng)計(jì)不了

那么如果一個(gè)表中沒有可以用來(lái)排序的列呢????

先drop掉t1表,再建立t1表,腳本如下:

View Code

結(jié)果是

(圖片十四)

我覺得SQLSERVER應(yīng)該會(huì)在表中加上一列,類似用來(lái)區(qū)分聚集索引頁(yè)面重復(fù)值的UNIQUIFIER(KEY)

當(dāng)查詢完畢之后就刪除掉這一列

(圖片十五)

 


非聚集索引表

SQL腳本如下:

View Code

(圖片十六)

大家一定要記住:非聚集索引是建立在c1列上的!!!

下面兩個(gè)SQL語(yǔ)句都是一樣的,都是根據(jù)c1列的值進(jìn)行統(tǒng)計(jì),而SQLSERVER只掃描非聚集索引頁(yè)面,而不掃描數(shù)據(jù)頁(yè)面

1 SELECT  COUNT(*) FROM [dbo].[nct1]2 3 SELECT  COUNT(3) FROM [dbo].[nct1]

SELECT  COUNT(*) FROM [dbo].[nct1]是不需要到數(shù)據(jù)頁(yè)面去讀取c2列的數(shù)據(jù)的,只需要掃描非聚集索引頁(yè)面(c1列)就可以了

SELECT  COUNT(3) FROM [dbo].[nct1]跟SELECT  COUNT(*) FROM [dbo].[nct1]也是一樣

不知道大家還記得書簽查找不,如果SQLSERVER掃描了非聚集索引頁(yè)面之后還需要到數(shù)據(jù)頁(yè)面去讀取其他字段的數(shù)據(jù)的話,就需要RID查找運(yùn)算符

(圖片十七)

SQLSERVER聚集索引與非聚集索引的再次研究(下)

SELECT  COUNT(*) FROM [dbo].[nct1]和SELECT  COUNT(3) FROM [dbo].[nct1]的掃描方式跟前面說(shuō)的聚集索引表是差不多的

這里就不一一敘述了~

 

而SELECT  COUNT(c2) FROM [dbo].[nct1]為什麼會(huì)用表掃描呢?

1 SELECT  COUNT(c2) FROM [dbo].[nct1]

c2列不在非聚集索引頁(yè)面里,所以需要表掃描

(圖片十八)

SELECT  COUNT(c2) FROM [dbo].[nct1]跟前面說(shuō)的堆表是差不多的,這里就不一一敘述了


總結(jié)

做了這麼多實(shí)驗(yàn)

可以總結(jié)出:select count(*)、count(數(shù)字)、count(字段名)是沒有性能差別的??!

我說(shuō)的沒有差別是在相同的條件下,就像非聚集索引表,如果使用

SELECT  COUNT(c2) FROM [dbo].[nct1]

SELECT  COUNT(*) FROM [dbo].[nct1]、SELECT  COUNT(3) FROM [dbo].[nct1]相比肯定有差別

因?yàn)?strong>SELECT  COUNT(c2) FROM [dbo].[nct1]走的是表掃描

如果SELECT  COUNT(c1) FROM [dbo].[nct1]

SELECT  COUNT(*) FROM [dbo].[nct1]、SELECT  COUNT(3) FROM [dbo].[nct1]相比是沒有差別的

(圖片十九)

大家走的都是非聚集索引掃描

 

無(wú)論是聚集索引表、堆表、非聚集索引表都是掃描表中的記錄來(lái)統(tǒng)計(jì)出表中的行數(shù)的

 

希望大家看完這篇文章之后,不再一知半解了,這是我的希望o(∩_∩)o

 

如有不對(duì)的地方,歡迎大家拍磚o(∩_∩)o

 

-----------------------------------------------------------------------

補(bǔ)上IO和時(shí)間的比較 2013-10-19

---------------------------------

聚集索引表

1 SET STATISTICS IO ON2 SET STATISTICS TIME ON3 GO4 SELECT COUNT(*) FROM [dbo].[ct1]
1 SQL Server 分析和編譯時(shí)間: 2    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 2 毫秒。3 4 (1 行受影響)5'ct1'。掃描計(jì)數(shù) 1,邏輯讀取 5 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。6 7 SQL Server 執(zhí)行時(shí)間:8    CPU 時(shí)間 = 15 毫秒,占用時(shí)間 = 2 毫秒。
1 SET STATISTICS IO ON2 SET STATISTICS TIME ON3 GO4 SELECT COUNT(1) FROM [dbo].[ct1]
1 SQL Server 分析和編譯時(shí)間: 2    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 2 毫秒。3 4 (1 行受影響)5'ct1'。掃描計(jì)數(shù) 1,邏輯讀取 5 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。6 7 SQL Server 執(zhí)行時(shí)間:8    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。
1 SET STATISTICS IO ON2 SET STATISTICS TIME ON3 GO4 SELECT COUNT(c1) FROM [dbo].[ct1]
1 SQL Server 分析和編譯時(shí)間: 2    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 1 毫秒。3 4 (1 行受影響)5'ct1'。掃描計(jì)數(shù) 1,邏輯讀取 5 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。6 7 SQL Server 執(zhí)行時(shí)間:8    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。

---------------------------------------------------

堆表

1 SET STATISTICS IO ON2 SET STATISTICS TIME ON3 GO4 SELECT COUNT(*) FROM [dbo].[t1]
 1 SQL Server 分析和編譯時(shí)間:  2    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 3  4 SQL Server 執(zhí)行時(shí)間: 5    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 6  7 SQL Server 執(zhí)行時(shí)間: 8    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 9 SQL Server 分析和編譯時(shí)間: 10    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。11 12 (1 行受影響)13't1'。掃描計(jì)數(shù) 1,邏輯讀取 12 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。14 15 SQL Server 執(zhí)行時(shí)間:16    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。
1 SET STATISTICS IO ON2 SET STATISTICS TIME ON3 GO4 SELECT COUNT(1) FROM [dbo].[t1]
 1 SQL Server 分析和編譯時(shí)間:  2    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 3  4 SQL Server 執(zhí)行時(shí)間: 5    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 6  7 SQL Server 執(zhí)行時(shí)間: 8    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 9 SQL Server 分析和編譯時(shí)間: 10    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 79 毫秒。11 12 (1 行受影響)13't1'。掃描計(jì)數(shù) 1,邏輯讀取 12 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。14 15 SQL Server 執(zhí)行時(shí)間:16    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。
1 SET STATISTICS IO ON2 SET STATISTICS TIME ON3 GO4 SELECT COUNT(c1) FROM [dbo].[t1]
 1 SQL Server 分析和編譯時(shí)間:  2    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 3  4 SQL Server 執(zhí)行時(shí)間: 5    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 6  7 SQL Server 執(zhí)行時(shí)間: 8    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 9 SQL Server 分析和編譯時(shí)間: 10    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 1 毫秒。11 12 (1 行受影響)13't1'。掃描計(jì)數(shù) 1,邏輯讀取 12 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。14 15 SQL Server 執(zhí)行時(shí)間:16    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。

-----------------------------------------------------------------------------------------

非聚集索引表

1 SET STATISTICS IO ON2 SET STATISTICS TIME ON3 GO4 SELECT COUNT(*) FROM [dbo].[nct1]
 1 SQL Server 分析和編譯時(shí)間:  2    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 3  4 SQL Server 執(zhí)行時(shí)間: 5    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 6  7 SQL Server 執(zhí)行時(shí)間: 8    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 9 SQL Server 分析和編譯時(shí)間: 10    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 1 毫秒。11 12 (1 行受影響)13'nct1'。掃描計(jì)數(shù) 1,邏輯讀取 2 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。14 15 SQL Server 執(zhí)行時(shí)間:16    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。
1 SET STATISTICS IO ON2 SET STATISTICS TIME ON3 GO4 SELECT COUNT(1) FROM [dbo].[nct1]
 1 SQL Server 分析和編譯時(shí)間:  2    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 3  4 SQL Server 執(zhí)行時(shí)間: 5    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 6  7 SQL Server 執(zhí)行時(shí)間: 8    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 9 SQL Server 分析和編譯時(shí)間: 10    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。11 12 (1 行受影響)13'nct1'。掃描計(jì)數(shù) 1,邏輯讀取 2 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。14 15 SQL Server 執(zhí)行時(shí)間:16    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 49 毫秒。
1 SET STATISTICS IO ON2 SET STATISTICS TIME ON3 GO4 SELECT COUNT(c1) FROM [dbo].[nct1]
 1 SQL Server 分析和編譯時(shí)間:  2    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 3  4 SQL Server 執(zhí)行時(shí)間: 5    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 6  7 SQL Server 執(zhí)行時(shí)間: 8    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。 9 SQL Server 分析和編譯時(shí)間: 10    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 0 毫秒。11 12 (1 行受影響)13'nct1'。掃描計(jì)數(shù) 1,邏輯讀取 2 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。14 15 SQL Server 執(zhí)行時(shí)間:16    CPU 時(shí)間 = 0 毫秒,占用時(shí)間 = 1 毫秒。

 

2014-6-21補(bǔ)充:

USE [sss]--建表CREATE TABLE counttb ( id INT NULL )--插入數(shù)據(jù)INSERT  INTO [dbo].[counttb]        ( [id] )        SELECT  1        UNION ALL        SELECT  NULL --統(tǒng)計(jì)行數(shù)SELECT  COUNT(1) ,        COUNT(*) ,        COUNT(id)FROM    [dbo].[counttb]--查詢索引的統(tǒng)計(jì)值SELECT  a.[rowcnt] ,        b.[name]FROM    sys.[sysindexes] AS a        INNER JOIN sys.[objects] AS b ON a.[id] = b.[object_id]WHERE   b.[name] = 'counttb'--創(chuàng)建非聚集索引CREATE INDEX ix_counttb_id ON [dbo].[counttb] (id)--統(tǒng)計(jì)行數(shù)SELECT  COUNT(1) ,        COUNT(*) ,        COUNT(id)FROM    [dbo].[counttb]

因?yàn)樵趧?chuàng)建非聚集索引前和創(chuàng)建非聚集索引后的行數(shù)值都是一樣的,可以看出COUNT(*) COUNT(1) 和COUNT(ID)

的統(tǒng)計(jì)方式不一樣,所以沒有可比性

一般我們?cè)诮y(tǒng)計(jì)行數(shù)的時(shí)候都會(huì)把NULL值統(tǒng)計(jì)在內(nèi)的,所以這樣的話,最好就是使用COUNT(*) 和COUNT(1) ,這樣的速度最快??!

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
in和exists的區(qū)別與執(zhí)行效率問題解析
Sql注射終點(diǎn)
固態(tài)硬盤和機(jī)械硬盤的比較和SQLSERVER在兩種硬盤上的性能差異
SQL Server讀懂語(yǔ)句運(yùn)行的統(tǒng)計(jì)信息 SET STATISTICS TIME IO PROFILE ON
論IP地址在數(shù)據(jù)庫(kù)中應(yīng)該用何種形式存儲(chǔ) - 吳秦(Saylor) - 博客園
Sql Server性能優(yōu)化輔助指標(biāo)SET STATISTICS TIME ON和SET STATISTICS IO ON
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服