1

我有一个更新查询:-

Update PM.Contractual_Allowances  Set Provider_ID = 3  Where Tenant_ID = 1 and Carrier_ID = 203

对于上述查询,我​​得到如下执行计划:

执行计划

我试图理解为什么当我没有 ORDER BY 子句时我会得到排序运算符以及我可以做些什么来避免它。

以下是文本中的计划(又名“Showplan_text”):

|--Sequence
   |--Index Update(OBJECT:([Ntier_Master].[PM].[Contractual_Allowances].[IX_Contractual_Allowances_Provider_ID_Tenant_ID]), SET:([Contractual_Allowance_ID1043] = [Ntier_Master].[PM].[Contractual_Allowances].[Contractual_Allowance_ID],[Provider_ID1044] = [Ntier_Master].[PM].[Contractual_Allowances].[Provider_ID],[Tenant_ID1045] = [Ntier_Master].[PM].[Contractual_Allowances].[Tenant_ID]) WITH ORDERED PREFETCH ACTION:([Act1042]))
   |    |--Sort(ORDER BY:([Ntier_Master].[PM].[Contractual_Allowances].[Provider_ID] ASC, [Ntier_Master].[PM].[Contractual_Allowances].[Tenant_ID] ASC, [Ntier_Master].[PM].[Contractual_Allowances].[Contractual_Allowance_ID] ASC, [Act1042] ASC))
   |         |--Filter(WHERE:(NOT [Expr1038]))
   |              |--Table Spool
   |                   |--Split
   |                        |--Clustered Index Update(OBJECT:([Ntier_Master].[PM].[Contractual_Allowances].[PK_Contractual_Allowances_Contractual_Allowance_ID]), SET:([Ntier_Master].[PM].[Contractual_Allowances].[Provider_ID] = [Expr1033],[Ntier_Master].[PM].[Contractual_Allowances].[Contractual_Allowance_TS] = [Expr1003]))
   |                             |--Compute Scalar(DEFINE:([Expr1038]=[Expr1038], [Expr1039]=[Expr1039]))
   |                                  |--Compute Scalar(DEFINE:([Expr1038]=CASE WHEN [Expr1007] THEN (1) ELSE (0) END, [Expr1039]=CASE WHEN [Expr1007] THEN (1) ELSE (0) END))
   |                                       |--Compute Scalar(DEFINE:([Expr1033]=(3)))
   |                                            |--Compute Scalar(DEFINE:([Expr1007]=CASE WHEN [Ntier_Master].[PM].[Contractual_Allowances].[Provider_ID] = (3) THEN (1) ELSE (0) END))
   |                                                 |--Compute Scalar(DEFINE:([Expr1003]=gettimestamp((10))))
   |                                                      |--Clustered Index Scan(OBJECT:([Ntier_Master].[PM].[Contractual_Allowances].[PK_Contractual_Allowances_Contractual_Allowance_ID]),  WHERE:([Ntier_Master].[PM].[Contractual_Allowances].[Tenant_ID]=(1) AND [Ntier_Master].[PM].[Contractual_Allowances].[Carrier_ID]=(203)) ORDERED FORWARD)
   |--Index Update(OBJECT:([Ntier_Master].[PM].[Contractual_Allowances].[IX_Contractual_Allowances_Carrier_ID_Location_ID_Department_ID_Tenant_ID]), SET:([Contractual_Allowance_ID1046] = [Ntier_Master].[PM].[Contractual_Allowances].[Contractual_Allowance_ID],[Modifiers1047] = [Ntier_Master].[PM].[Contractual_Allowances].[Modifiers],[Carrier_ID1048] = [Ntier_Master].[PM].[Contractual_Allowances].[Carrier_ID],[Procedure_Code_ID1049] = [Ntier_Master].[PM].[Contractual_Allowances].[Procedure_Code_ID],[Location_ID1050] = [Ntier_Master].[PM].[Contractual_Allowances].[Location_ID],[Provider_ID1051] = [Ntier_Master].[PM].[Contractual_Allowances].[Provider_ID],[Department_ID1052] = [Ntier_Master].[PM].[Contractual_Allowances].[Department_ID],[Tenant_ID1053] = [Ntier_Master].[PM].[Contractual_Allowances].[Tenant_ID]) WITH ORDERED PREFETCH ACTION:([Act1042]))
        |--Sort(ORDER BY:([Ntier_Master].[PM].[Contractual_Allowances].[Carrier_ID] ASC, [Ntier_Master].[PM].[Contractual_Allowances].[Location_ID] ASC, [Ntier_Master].[PM].[Contractual_Allowances].[Department_ID] ASC, [Ntier_Master].[PM].[Contractual_Allowances].[Tenant_ID] ASC, [Ntier_Master].[PM].[Contractual_Allowances].[Contractual_Allowance_ID] ASC, [Act1042] ASC))
             |--Filter(WHERE:(NOT [Expr1039]))
                  |--Table Spool




 CREATE NONCLUSTERED INDEX IX_Contractual_Allowances_Location_ID_Tenant_ID ON PM.Contractual_Allowances (  Location_ID ASC  , Tenant_ID ASC  )   WITH (  PAD_INDEX =  OFF ,FILLFACTOR = 100  ,SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF , STATISTICS_NORECOMPUTE = OFF , DROP_EXISTING = ON , ONLINE = OFF , ALLOW_ROW_LOCKS = ON , ALLOW_PAGE_LOCKS = ON  ) ON [PRIMARY ] 
 CREATE NONCLUSTERED INDEX IX_Contractual_Allowances_Provider_ID_Tenant_ID ON PM.Contractual_Allowances (  Provider_ID ASC  , Tenant_ID ASC  )   WITH (  PAD_INDEX =  OFF ,FILLFACTOR = 100  ,SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF , STATISTICS_NORECOMPUTE = OFF , DROP_EXISTING = ON , ONLINE = OFF , ALLOW_ROW_LOCKS = ON , ALLOW_PAGE_LOCKS = ON  ) ON [PRIMARY ] 
 CREATE NONCLUSTERED INDEX IX_Contractual_Allowances_Carrier_ID_Current_Effective_Date_Tenant_ID ON PM.Contractual_Allowances (  Carrier_ID ASC  , Current_Effective_Date ASC  , Tenant_ID ASC  )   WITH (  PAD_INDEX =  OFF ,FILLFACTOR = 100  ,SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF , STATISTICS_NORECOMPUTE = OFF , DROP_EXISTING = ON , ONLINE = OFF , ALLOW_ROW_LOCKS = ON , ALLOW_PAGE_LOCKS = ON  ) ON [PRIMARY ] 
 CREATE NONCLUSTERED INDEX IX_Contractual_Allowances_Carrier_ID_Location_ID_Department_ID_Tenant_ID ON PM.Contractual_Allowances (  Carrier_ID ASC  , Location_ID ASC  , Department_ID ASC  , Tenant_ID ASC  )   INCLUDE ( Modifiers , Procedure_Code_ID , Provider_ID )  WITH (  PAD_INDEX =  OFF ,FILLFACTOR = 100  ,SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF , STATISTICS_NORECOMPUTE = OFF , DROP_EXISTING = ON , ONLINE = OFF , ALLOW_ROW_LOCKS = ON , ALLOW_PAGE_LOCKS = ON  ) ON [PRIMARY ] 
CREATE NONCLUSTERED INDEX IX_Contractual_Allowances_Procedure_Code_ID_Tenant_ID ON PM.Contractual_Allowances (  Procedure_Code_ID ASC  , Tenant_ID ASC  )   WITH (  PAD_INDEX =  OFF ,FILLFACTOR = 100  ,SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF , STATISTICS_NORECOMPUTE = OFF , DROP_EXISTING = ON , ONLINE = OFF , ALLOW_ROW_LOCKS = ON , ALLOW_PAGE_LOCKS = ON  ) ON [PRIMARY ] 
4

1 回答 1

3

ORDER BY 子句不是唯一导致排序的东西。GROUP BY、DISTINCT、窗口排序函数(例如 ROW_NUMBER、RANK)、窗口聚合函数(例如 SUM() OVER (PARTITION BY ...)、窗口框架函数(例如 LAG 和 LEAD)是导致排序的许多因素之一。

当我们添加索引时,我们对数据进行了预排序,以便在查询时不需要对其进行排序。执行计划中的排序意味着 (1) 没有可用于处理排序的索引或 (2) 是可以处理排序但优化器选择不使用它的索引。考虑以下示例数据:

if object_id('tempdb..#sometable') is not null drop table #sometable;
create table #sometable (col1 int, col2 int);
insert #sometable values(1,10),(1,20),(2,15),(2,50),(3,10);

接下来,在启用“包括实际执行计划”的情况下运行这些查询。

select col1, max(col2)
from #sometable
group by col1;

select distinct col1
from #sometable;

select col1, col2, avg(col2) over (partition by col1)
from #sometable;

select col1, col2, avg(col2) over (partition by col1 order by (select null))
from #sometable;

注意执行计划:

在此处输入图像描述

您可以通过将鼠标悬停在排序运算符上来获取有关排序内容的更多信息:

在此处输入图像描述

这里需要对 col1 进行排序,所以让我们添加这个索引,运行查询并检查执行计划:

--alter table #sometable
create clustered index uq_sometable on #sometable(col1);

现在新的执行计划:

在此处输入图像描述

如您所见,所有种类都消失了。这个主题还有很多内容,但希望这可以帮助您了解如何在没有 ORDER BY 的情况下进行排序以及如何摆脱它们。

于 2017-09-21T15:51:52.167 回答