SQL优化,列列表上的条件会影响优化吗?
Posted
技术标签:
【中文标题】SQL优化,列列表上的条件会影响优化吗?【英文标题】:SQL Optimization, Does conditions on column list affect optimization? 【发布时间】:2018-03-26 08:50:35 【问题描述】:我觉得标题不够清楚(请指教)
假设我有这个假设的查询
SELECT
Name,
P.Amount,
count(DISTINCT PI.Id)
FROM Customer C
LEFT JOIN Purchase P ON C.Id = P.CustomerId
LEFT JOIN Flags F ON P.Id = F.PurchaseId AND F.Name = 'showItems'
LEFT JOIN PurchseItems PI ON PI.PurchseId = P.Id AND F.Value = 'TRUE'
WHERE C.Id = @customerId
GROUP BY Name, P.Amount, F.Value
或者
SELECT
Name,
P.Amount,
CASE WHEN F.Value = 'TRUE' THEN count(DISTINCT PI.Id) ELSE 0 END As ItemsCount
FROM Customer C
LEFT JOIN Purchase P ON C.Id = P.CustomerId
LEFT JOIN Flags F ON P.Id = F.PurchaseId AND F.Name = 'showItems'
LEFT JOIN PurchseItems PI ON PI.PurchseId = P.Id
WHERE C.Id = @customerId
GROUP BY Name, P.Amount, F.Value
无论如何,其中一个会帮助查询优化器吗?我正在使用 MS SQL 服务器。我想知道列列表上的条件是否有影响?
我的猜测是,如果F.Value
不是'True'
,则查询根本不必通过加入PurchaseItems
。
编辑:在 Group by 中添加了 F.Value
,因为它在每次购买时都是唯一的
我没有将其移近计数以保持查询或多或少相同。这个问题的想法是比较连接和选择列表的条件。
【问题讨论】:
当然您可以自己检查差异,只需运行两个查询。假设有一个 GROUP BY 你的第二个查询根本不会运行,它应该是COUNT( DISTINCT CASE WHEN F.Value = 'TRUE' THEN PI.Id END As ItemsCount
。否则无论如何都必须检查条件,最昂贵的操作将是 DISTINCT。
@dnoeth 您忘记在 SQL 中关闭括号。 :)
您不能拥有没有分组依据的聚合。编写有效的查询并比较执行计划。
语法仍然无效。
当您将 CASE 移动到 COUNT 中时,您将获得 working 查询,目前您只会收到一条错误消息:Msg 8120 Level 16 State 1 Line 1 列“F.Value”在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。
【参考方案1】:
如果有一些记录 F.Value 'TRUE'
,您的第一个查询比第二个查询要好第一次查询将过滤记录到点或更少的记录。所以查询会很快。
实际行数会更少。
第二次查询将获取更多结果集,然后再次应用 case 语句来获取正确的 ItemCount。
实际行数会更多。
不对您的其余查询或要求发表评论。
【讨论】:
【参考方案2】:一般来说: SELECTION(ON 子句和 WHERE 子句)越具体,您为优化器提供优化的句柄就越多。 在此基础上,您的第一个查询应该是最好的查询。
运行两个查询:
-- dbcc dropcleanbuffers -- 清理数据缓存。
-- dbcc freeproccache -- 清理编码缓存。
开启统计时间
设置统计 IO 开启
获得有关查询费用的印象。
本
【讨论】:
以上是关于SQL优化,列列表上的条件会影响优化吗?的主要内容,如果未能解决你的问题,请参考以下文章