And*_*elt 8 join sql-server subquery
这是我在 Stack Overflow 上的问题的转贴。他们建议在这里问:
我在2005 年找到了一篇在线文章,作者声称,许多开发人员使用 GROUP BY 是错误的,您最好将其替换为子查询。
我已经在我的一个查询中对其进行了测试,我需要根据另一个表中连接条目的数量对搜索结果进行排序(更常见的条目应该首先出现)。我最初的经典方法是将两个表连接到一个公共 ID,按选择列表中的每个字段分组,并按子表的计数对结果进行排序。
现在,来自链接博客的 Jeff Smith 声称,您最好使用一个子选择,它执行所有分组,而不是加入该子选择。检查这两种方法的执行计划,SSMS 指出,大组需要 52% 的时间,子选择需要 48%,所以从技术角度来看,子选择方法实际上要快一点。但是,“改进”的 SQL 命令似乎生成了更复杂的执行计划(就节点而言)
你怎么认为?您能否详细说明在这种特定情况下如何解释执行计划,以及哪一个通常是更可取的选择?
SELECT
a.ID,
a.ID_AddressType,
a.Name1,
a.Name2,
a.Street,
a.Number,
a.ZipCode,
a.City,
a.Country
FROM dbo.[Address] a
INNER JOIN CONTAINSTABLE(
dbo.[Address],
FullAddress,
'"ZIE*"',
5
) s ON a.ID = s.[KEY]
LEFT JOIN dbo.Haul h ON h.ID_DestinationAddress = a.ID
GROUP BY
a.ID,
a.ID_AddressType,
a.Name1,
a.Name2,
a.Street,
a.Number,
a.ZipCode,
a.City,
a.Country,
s.RANK
ORDER BY s.RANK DESC, COUNT(*) DESC;
SELECT
a.ID,
a.ID_AddressType,
a.Name1,
a.Name2,
a.Street,
a.Number,
a.ZipCode,
a.City,
a.Country
FROM dbo.[Address] a
INNER JOIN CONTAINSTABLE(
dbo.[Address],
FullAddress,
'"ZIE*"',
5
) s ON a.ID = s.[KEY]
LEFT JOIN (
SELECT ID_DestinationAddress, COUNT(*) Cnt
FROM dbo.Haul
GROUP BY ID_DestinationAddress
) h ON h.ID_DestinationAddress = a.ID
ORDER BY s.RANK DESC, h.Cnt DESC;
Run Code Online (Sandbox Code Playgroud)
如果将左连接更改dbo.Haul
为子查询,它将ID_DestinationAddress
在从扫描中获取数据后直接计算(流聚合)的这些不同值并对其进行计数(计算标量)。
这是您在执行计划中看到的:
而使用该GROUP BY
方法时,它仅在数据通过dbo.Haul
和之间的左连接后进行分组dbo.[Address]
。
它有多好将取决于 dbo.Haul 的唯一值比率。更少的唯一值意味着第二个执行计划的结果更好,因为左连接必须处理更少的值。
第二个查询的另一个肯定结果是只ID_DestinationAddress
计算了的唯一性,而不是 group by 中所有列作为一个整体的唯一性。
同样,您应该测试和验证查询、数据集和索引的结果。测试您是否不熟悉执行计划的方法之一是SET STATISTICS IO, TIME ON;
在执行查询之前进行设置,并通过将这些运行时统计信息粘贴到诸如statisticsparser 之类的工具中来使这些运行时统计信息更具可读性。
一个小测试,显示数据的差异可以为这些查询做什么。
如果该dbo.Haul
表与FULLTEXT索引过滤返回的5条记录匹配的不多,则差异不大:
1000 行可以更早地过滤,但无论如何在我的机器上,这两个查询的执行时间约为 15毫秒。
现在,如果我更改我的数据,那么这 5 条记录dbo.Haul
在左连接中有更多匹配项:
group by 查询的区别
<QueryTimeStats CpuTime="1564" ElapsedTime="1566" />
Run Code Online (Sandbox Code Playgroud)
并且子查询变得更加清晰
和统计数据:
<QueryTimeStats CpuTime="680" ElapsedTime="690"/>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1552 次 |
最近记录: |