-2
下面有兩個查詢,其中ID列的返回計數不包括空值 ,第二個查詢將返回表中所有行的計數,包括NULL行。選擇計數(ID)和選擇計數(*)之間的性能差異
select COUNT(ID) from TableName
select COUNT(*) from TableName
我的困惑: 有任何性能差異嗎?
下面有兩個查詢,其中ID列的返回計數不包括空值 ,第二個查詢將返回表中所有行的計數,包括NULL行。選擇計數(ID)和選擇計數(*)之間的性能差異
select COUNT(ID) from TableName
select COUNT(*) from TableName
我的困惑: 有任何性能差異嗎?
TL/DR:計劃可能是不一樣的,你應該測試適當的 數據,並確保您有正確的索引,然後選擇基於你的研究的最佳解決方案。
查詢計劃可能不相同,這取決於COUNT函數中使用的列的索引和可空性。
在下面的示例中,我創建一個表並填充一百萬行。 除列'b'外,所有列都已被編入索引。
結論是,其中一些查詢確實導致相同的執行計劃,但其中大多數不同。
這是在SQL Server 2014上測試的,目前我還沒有訪問2012的實例。你應該自己測試以找出最佳解決方案。
create table t1(id bigint identity,
dt datetime2(7) not null default(sysdatetime()),
a char(800) null,
b char(800) null,
c char(800) null);
-- We will use these 4 indexes. Only column 'b' does not have any supporting index on it.
alter table t1 add constraint [pk_t1] primary key NONCLUSTERED (id);
create clustered index cix_dt on t1(dt);
create nonclustered index ix_a on t1(a);
create nonclustered index ix_c on t1(c);
insert into T1 (a, b, c)
select top 1000000
a = case when low = 1 then null else left(REPLICATE(newid(), low), 800) end,
b = case when low between 1 and 10 then null else left(REPLICATE(newid(), 800-low), 800) end,
c = case when low between 1 and 192 then null else left(REPLICATE(newid(), 800-low), 800) end
from master..spt_values
cross join (select 1 from master..spt_values) m(ock)
where type = 'p';
checkpoint;
-- All rows, no matter if any columns are null or not
-- Uses primary key index
select count(*) from t1;
-- All not null,
-- Uses primary key index
select count(id) from t1;
-- Some values of 'a' are null
-- Uses the index on 'a'
select count(a) from t1;
-- Some values of b are null
-- Uses the clustered index
select count(b) from t1;
-- No values of dt are null and the table have a clustered index on 'dt'
-- Uses primary key index and not the clustered index as one could expect.
select count(dt) from t1;
-- Most values of c are null
-- Uses the index on c
select count(c) from t1;
現在,如果我們在我們想要我們的計數做更明確,會發生什麼?如果我們告訴查詢規劃者,我們只想獲得非空的行,這會改變什麼嗎?
-- Homework!
-- What happens if we explicitly count only rows where the column is not null? What if we add a filtered index to support this query?
-- Hint: It will once again be different than the other queries.
create index ix_c2 on t1(c) where c is not null;
select count(*) from t1 where c is not null;
邏輯會指示NULL的測試會減慢速度 - 除非您有數百萬條記錄,否則差異可能以毫秒爲單位。 – rheitzman
@Kamil:雖然相似,但這不是同一個問題。您的鏈接與3種不同的表達查詢的方式有關,它們會生成完全相同的結果。在這種情況下,2個查詢不會返回相同的結果。根據OP的描述,「ID」可以是空的,但這很奇怪。我希望OP的描述是正確的。 – sstan
'TableName'的定義是什麼?你是在暗示「ID」是否真的可以空?奇怪的名字,如果是。你有什麼指數? – sstan