lif*_*ney 5 sql-server optimization query-performance
我有以下表格
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)
Run Code Online (Sandbox Code Playgroud)
这些选择中哪一个会表现更好?
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
Run Code Online (Sandbox Code Playgroud)
以下是两个 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 时是否存在性能差异?
J.D*_*.D. 11
从我看来,这两个计划是相同的。
事实上,在这种情况下,您将获得相同形状的查询计划。情况并非总是如此。
执行 select * order by 与 select column order by 时是否存在性能差异?
是的,即使在您的情况下具有相同形状的查询计划,也存在性能差异(尽管在这种特定情况下可能可以忽略不计)。暂时忘记ORDER BY
该子句,让我们只讨论SELECT *
vs SELECT OneSingleColumn
,因为无论如何,以下内容都是正确的:
选择比需要更多的列(在本例中为 7 个额外列)SELECT *
需要定位更多数据,将其从磁盘加载到内存中,进行处理并通过网络传输给消费者。在您的架构中,这 7 个额外列每行最多可以包含大约半 KB 的额外数据。在一个大小合适的表中,假设有 1 亿行,那么执行上述所有步骤将需要额外 50 GB 的数据。
它可以/将导致分配更多资源来服务查询,以支持附加列的所有上述步骤。这减少了服务器上同时运行的其他查询可用的资源。
它可以通过多种不同的方式产生不同形状的计划。当查询超过临界点时,最常见的方法之一是对SELECT *
查询的版本进行扫描操作,而不是对版本进行有效的搜索。或者另一种方法是,当一个查询计划使用完全不同的索引时,在您只需要.SELECT OneSingleColumn
OneSingleColumn
影响性能的计划形状可能变化的一种方式(如 maple_shaft 所指出的)是,即使在最好的情况下,在最合适的索引上进行索引查找来服务查询,它也可能不会包含所有字段, IE *
。因此,您最终会得到一个额外的键查找运算符,从而导致从聚集索引中查找剩余字段的额外工作。或者,在不太理想的结果中,您最终会扫描聚集索引来满足查询,而不是寻找更优化的索引,该索引仅包含您感兴趣的列SELECT
(假设您的索引适当地满足您的疑问)。当您只SELECT
需要您需要的列,并且有一个覆盖这些列的索引时,则可以使用最佳索引来为您的查询提供服务,而无需进行额外的操作/工作,并且您很有可能获得也针对该索引进行查找操作,速度相当快。
SELECT *
出于多种原因,它也是一种反模式,不仅与性能有关,还与可读性和可维护性有关:
这种情况下的差异可以在 SORT 运算符上看到。行大小 27B 与 139B。有 20 行且大小不同,在这种情况下不是问题。对于更宽的表和更多的行,我们可以讨论 KB 与 MB,甚至 GB 数据,具体取决于数据。
从实际经验来看,从用户的角度来看,存在 KB 与 GB 排序差异以及实际性能差异。
归档时间: |
|
查看次数: |
3655 次 |
最近记录: |