当我使用执行计划执行以下查询时。我可以看到“排序”是最昂贵的任务。但我没有在查询中使用任何排序选项。为什么会这样?在选择之前存在嵌套循环连接任务。另外请告诉我有关合并连接、散列连接和嵌套循环连接的信息。
select
Ename from dbo.Employee e
where
Salary>(
select AVG(Salary) from dbo.Employee where
DeptId=e.DeptId
group by DeptId)
当我使用执行计划执行以下查询时。我可以看到“排序”是最昂贵的任务。但我没有在查询中使用任何排序选项。为什么会这样?在选择之前存在嵌套循环连接任务。另外请告诉我有关合并连接、散列连接和嵌套循环连接的信息。
select
Ename from dbo.Employee e
where
Salary>(
select AVG(Salary) from dbo.Employee where
DeptId=e.DeptId
group by DeptId)
它必须进行排序以确定每个 TerritoryID哪些行的薪水较低- 所以排序是因为这种分区/分组。
您可以使用索引摆脱排序操作,例如:
CREATE INDEX d_s ON dbo.Employee(DeptId, Salary);
但是您必须确定此查询的收益(在执行频率的背景下)是否证明了附加索引的合理性——这可能会影响您工作负载的其他部分。您将在某个时候为排序/分组付费。
同样,仅仅因为您的查询中的成本很高,并不意味着这是一个问题。这个查询慢吗?即使是一级方程式比赛也有一辆“慢速”赛车以最后一名完赛。
在您的 SQL 查询中,您实际将数据排序到列上的组(Ename)排序可能是性能瓶颈,但您需要找出。如果排序确实导致性能问题,那么您可以按照 Aaaroon Bertrand 的建议将其移动到索引。
嵌套连接的原因是 SQLserver 实际上执行了 2 次查询以返回您的结果。
一个是写在子查询中的 Avg(Salary),另一个是外部查询,它从 Employee Table 中选择 Ename,这是使用 Clustered index Scan 完成的。然后组合这两个查询以返回所需的结果。它基本上是将子查询中的每一行与满足谓词的外部查询中的每一行进行比较。
合并连接只有在连接列上有索引时才有可能。合并连接有时非常快,因为它们已经排序。