在關於SQL的問題中,爲示例數據包含DDL + DML總是很好。我將在本文末尾添加一個腳本,它將使用CTE生成一堆測試數據。
經過一些測試,我發現連接更高性能。
如果針對單個項目ID(其中item.itemid = 500,例如)針對彼此運行2個查詢,則每個查詢的成本爲50%。
如果使用範圍 - 在這種情況下,爲itemid 200和8000之間,查詢成本開始真正有利於連接(19%至81%),以及加入執行得更快一致。
我檢查的速度是這樣的:
declare @start datetime
set @start = getdate()
Query 1
select getdate() - @start
set @start = getdate()
Query 2
select getdate() - @start
如果增加範圍200和80000之間爲itemid,你看到更多的分離 - 查詢費用就像是5%至95 %贊成連接,並且連接在我的方案中執行〜330 MS,對於替代查詢,執行〜420 MS。
有什麼真正的獨特之處的where子句?也許有一個可控性問題或其他問題。
這裏的DDL/DML,創建100個客戶,〜1000個設施,〜10000個項目,〜10萬級的物品:
create table customer (customerid int primary key,customerinfo varchar(25))
create table facility (facilityid int primary key, customerid int foreign key references customer(customerid))
create table project (projectid int primary key, facilityid int foreign key references facility(facilityid))
create table item (itemid int primary key, iteminfo varchar(25), projectid int foreign key references project(projectid))
GO
;with cte as
(select 1 as id, 'customer' + cast(1 as varchar(5)) as info
union all
select cte.id + 1 as id, 'customer' + cast(cte.id + 1 as varchar(5))
from cte
where cte.id < 100)
insert into customer select id, info from cte
option(maxrecursion 100)
GO
;with cte as
(select 1 as id, 1 as customerid
union all
select cte.id + 1, ((cte.id + 1)/10) + 1
from cte
where cte.id < 999)
insert into facility select id, customerid from cte
option(maxrecursion 1000)
GO
;with cte as
(select 1 as id, 1 as facilityid
union all
select cte.id + 1, ((cte.id + 1)/10) + 1
from cte
where cte.id < 9989)
insert into project select id, facilityid from cte
option(maxrecursion 10000)
GO
;with cte as
(select 1 as id, 1 as projectid, 'item' + cast(1 as varchar(5)) as iteminfo
union all
select cte.id + 1, ((cte.id + 1)/10) + 1, 'item' + cast(cte.id + 1 as varchar(5))
from cte
where cte.id < 99889)
insert into item select id, iteminfo, projectid from cte
option(maxrecursion 0)
GO
沒有辦法確切知道W/O看到實際的執行計劃這兩個查詢。 –
個人喜好,你可能通過第二種方式獲得的最小收益被它的可讀性/可維護性遠遠抵消。 –
加入肯定應該有更好的表現。你的桌子有多少行?嘗試執行具有數百萬行的查詢。 – Fabio