【问题标题】:SQL Server : slow query with 3 "OR" condition and order by IdSQL Server:具有 3 个“OR”条件和按 ID 排序的慢速查询
【发布时间】:2018-09-20 08:17:07
【问题描述】:

我的查询:

SELECT TOP 30 a.*  
FROM Car 
WHERE (ModelId = 642 AND RegionId IN (23, 63, 1, 30, 5, 6, 7, 9, 15)) OR
      (ModelId = 242 AND RegionId IN (23, 63, 1, 30, 5, 6, 7, 9, 15, 26)) OR 
      (ModelId = 334 AND RegionId IN (23, 63, 1, 30, 5, 6, 7, 9, 15, 26)) 
ORDER BY Id DESC

它在 30 秒内执行。

如果我删除 order by Id 部分,它会在 1 秒内执行。

或者如果我删除一个OR 条件,它也会在 1 秒内执行。

WHERE (ModelId = 642 AND RegionId IN (23, 63, 1, 30, 5, 6, 7, 9, 15)) OR    
      (ModelId = 242 AND RegionId IN (23, 63, 1, 30, 5, 6, 7, 9, 15, 26)) 
ORDER BY Id DESC

ModelIdRegionId 列具有索引。 Id 是主键。

执行计划显示 97% 的聚集索引搜索了 Id。

请帮帮我。为什么ORDER BY 3 OR 条件这么慢?

【问题讨论】:

  • 考虑用 union 替换或替换 - 无论何时你按它订购都会减慢查询速度
  • 我明白了。我为并行添加了一个选项 OPTION(QUERYTRACEON 8649),查询在 1 秒内执行。奇怪的是mssql没有猜到自己
  • 所以用 union 代替你会加快速度吗?
  • 丹尼尔马库斯,是的。使用 2 或条件 mssql 以并行方式执行它,但使用 3 或不使用它。一切都已决定
  • 非常有趣-感谢分享

标签: sql sql-server performance select sql-order-by


【解决方案1】:

您可以尝试扩展OR(来自Oracle,但想法相同):

OR 扩展是一种可用于优化析取查询(包含 OR 子句的查询)的转换。

OR 扩展的基本思想是将包含析取的查询转换为两个或多个分支的 UNION ALL 查询的形式。这是通过将析取拆分为其组件并将每个组件与 UNION ALL 查询的分支相关联来完成的。

WITH cte AS (
   SELECT * 
   FROM Car
   WHERE ModelId = 642 AND RegionId IN (23,63,1,30,5,6,7,9,15)
   UNION ALL
   SELECT * 
   FROM Car
   WHERE ModelId = 242 AND RegionId IN (23,63,1,30,5,6,7,9,15,26)
   UNION ALL
   SELECT *
   FROM car
   WHERE ModelId = 334 AND RegionId IN (23,63,1,30,5,6,7,9,15,26)
)
SELECT TOP 30 *
FROM cte
ORDER BY id DESC;

【讨论】:

  • 不妨将其设为 UNION ALL,这样就不必检查重复项。
【解决方案2】:

可能会更糟

SELECT TOP 30 a.*  
FROM Car 
WHERE (ModelId in (642, 242, 334) AND RegionId IN (23, 63, 1, 30, 5, 6, 7, 9, 15)) 
   OR (ModelId in (242, 334) AND RegionId  = 26)
ORDER BY Id DESC

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多