Sql-Server
Select * Order by vs Select column 按性能排序
我有以下表格
Create Table dbo.product ( productId varchar(100) primary key, productStatus varchar(100), productRegion varchar(100), productCreated datetime, productUpdated datetime ) Go declare @id int = 1 while @id <= 100 Begin Insert Into dbo.product values ('product'+cast(@id as varchar(10)),'Active','North',getdate(),getdate()) set @id = @id + 1 End set @id = 1 while @id <= 100 Begin Insert Into dbo.product values ('inprod'+ cast(@id as varchar(10)),'InActive','South',getdate(),getdate()) set @id = @id + 1 End Go Create Table dbo.productRef ( productRef int Identity(1,1) primary key, productId varchar(100), productName varchar(100) ) Go Insert Into dbo.productRef (productId) Select top 20 productId from dbo. product Go declare @id int = 1 while @id <= 20 Begin update dbo.productRef set productName = 'productName'+convert(varchar(10),@id) where productRef = @id set @id = @id + 1 End Go Create nonclustered index idx_productRef1 On dbo.productRef(productId)
這些選擇中的哪一個會表現得更好?
select p.* from dbo.product p join dbo.productref pr on p.productid = pr.productid order by p.productUpdated select p.productId from dbo.product p join dbo.productref pr on p.productid = pr.productid order by p.productUpdated
這是兩個 select 語句的查詢計劃:
select * plan:
https://www.brentozar.com/pastetheplan/?id=SyY21P0Jo
select productId plan:
https://www.brentozar.com/pastetheplan/?id=BkK -gwA1i
從我看到的兩個計劃是相同的。執行 select * order by 與 select column order by 時是否存在性能差異?
從我看到的兩個計劃是相同的。
實際上,在這種情況下,您將獲得相同形狀的查詢計劃。情況並非總是如此。
執行 select * order by 與 select column order by 時是否存在性能差異?
是的,即使在您使用相同形狀的查詢計劃的情況下,也存在性能差異(儘管在這種特定情況下可能可以忽略不計)。暫時忘記該
ORDER BY
子句,讓我們談談SELECT *
vsSELECT OneSingleColumn
,因為無論如何以下都是正確的:
- 選擇比需要更多的列(在這種情況下是 7 個額外的列)
SELECT *
需要定位更多的數據,將其從磁碟載入到記憶體中,進行處理,然後通過網路傳輸給消費者。在您的架構中,這 7 個額外的列每行最多可以包含大約 0.5 KB 的額外數據。在一個大小合適的表中,比如 1 億行大,這將是一個額外的 50 GB 數據,需要執行所有上述步驟。- 它可以/將導致分配更多資源來為查詢提供服務,以支持其他列的所有上述步驟。這減少了本可用於伺服器上同時執行的其他查詢的資源。
- 它可以以多種不同的方式產生不同形狀的計劃。當查詢超過臨界點時,最常見的方法之一是獲取
SELECT *
查詢版本的掃描操作,而不是有效地尋找版本。或者另一種方式是,當一個查詢計劃使用完全不同的索引,而不是在您只需要.SELECT OneSingleColumn``OneSingleColumn
- 計劃的形狀可能會發生變化(如 maple_shaft 指出的)影響性能的一種方式是,即使在最佳情況下,在最合適的索引上進行索引查找以服務於查詢,它也可能不會包含所有欄位,即
*
。因此,您最終會得到一個額外的鍵查找運算符,這會導致額外的工作來從聚集索引中查找剩餘的欄位。或者在一個不太理想的結果中,您最終會掃描聚集索引以滿足查詢,而不是尋找一個更優化的索引,該索引只包含您感興趣的列SELECT
(假設您的索引適當地滿足您的查詢)。當你只SELECT
您需要的列,並且有一個涵蓋這些列的索引,然後可以使用最佳索引來為您提供查詢,而無需進行額外的操作/工作,並且您很有可能會獲得查找操作也針對該指數,速度非常快。
SELECT *
出於多種原因,它也是一種反模式,不僅與性能有關,還與可讀性和可維護性有關: