sql count(*) vs count(1)

24
MS SQL 123 1

Upload: rainmaker-ho

Post on 09-Jan-2017

88 views

Category:

Software


3 download

TRANSCRIPT

Page 1: SQL Count(*) VS Count(1)

1

MS SQL 123

Page 2: SQL Count(*) VS Count(1)

2

SELECT COUNT (*) FROM mytable 一定會使用 Table Scan?

Page 3: SQL Count(*) VS Count(1)

3

NO

Page 4: SQL Count(*) VS Count(1)

4

SQL 會用最小 i/o 成本的方式選擇最小的 Page Number

Page 5: SQL Count(*) VS Count(1)

5

DEMO

Page 6: SQL Count(*) VS Count(1)

6

CREATE TABLE CTest (c1 INT IDENTITY, c2 BIGINT DEFAULT 1, c3 CHAR (1000) DEFAULT 'a');GOSET NOCOUNT ON;GOINSERT INTO CTest DEFAULT VALUES;GO 10000

Page 7: SQL Count(*) VS Count(1)

7

開啟實際的執行計畫 Enable execution plan viewers in SSMS

Include Actual Execution Plan

Page 8: SQL Count(*) VS Count(1)

8

SELECT COUNT (*)

SELECT COUNT (*) from CTest;

Page 9: SQL Count(*) VS Count(1)

9

加入 NonClustered Index – c2 (BIGINT)

CREATE NONCLUSTERED INDEX CTest_1 ON CTest (c2);

Page 10: SQL Count(*) VS Count(1)

10

SELECT COUNT (*) SELECT COUNT (*) from CTest;

變成了 Index Scan 因為使用 CTest_1 index 會比使用 Table Scan 使用更少的 i/o

Page 11: SQL Count(*) VS Count(1)

11

加入 NonClustered Index – c1 (INT)

CREATE NONCLUSTERED INDEX CTest_2 ON CTest (c1);

Page 12: SQL Count(*) VS Count(1)

12

SELECT COUNT (*) SELECT COUNT (*) from CTest;

跟 CTest_1 Index 相比 CTest_2 Index 使用更少的 i/o

Page 13: SQL Count(*) VS Count(1)

13

看一下每個 Index 的 Page CountSELECT a.[index_id], a.[page_count], b.name AS index_nameFROM sys.dm_db_index_physical_stats(DB_ID (), OBJECT_ID ('CTest'), NULL, NULL, 'LIMITED') aINNER JOIN sys.indexes bON a.object_id = b.object_id AND a.index_id = b.index_id;

Page 14: SQL Count(*) VS Count(1)

14

Page 15: SQL Count(*) VS Count(1)

15

Count(*) or

Count(1)

Page 16: SQL Count(*) VS Count(1)

16

50/50

Page 17: SQL Count(*) VS Count(1)

17

GUID是一個好的Cluster Key?

Page 18: SQL Count(*) VS Count(1)

18

NO

Page 19: SQL Count(*) VS Count(1)

19

RandomIndex fragmentation

16 bytes long

Page 20: SQL Count(*) VS Count(1)

20

DEMO

Page 21: SQL Count(*) VS Count(1)

21

建立測試的資料表create table tblSAMPLE_1(xnewid uniqueidentifier default(newid()) primary key, xname varchar(10) );go

insert into tblSAMPLE_1(xname) values('rainmaker')go 500

Page 22: SQL Count(*) VS Count(1)

22

查看 Index 的破碎狀況

Page 23: SQL Count(*) VS Count(1)

23

大於 30% 就 Rebuild Index

Page 24: SQL Count(*) VS Count(1)

24

查看 Table 各 Index 的破碎狀況SELECT a.index_id, name, avg_fragmentation_in_percentFROM sys.dm_db_index_physical_stats (DB_ID(N'tempdb'), OBJECT_ID(N'tblSAMPLE_1'), NULL, NULL, NULL) AS a JOIN sys.indexes AS b ON a.object_id = b.object_id AND a.index_id = b.index_id;