SQL 服务器:使用 3 "OR" 条件和按 ID 排序的慢查询

SQL Server : slow query with 3 "OR" condition and order by Id

我的查询:

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 条件这么慢?

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

OR expansion is a transformation that can be used to optimize disjunctive queries (queries that contain OR clauses).

The basic idea in OR expansion is to transform a query containing disjunctions into the form of a UNION ALL query of two or more branches. This is done by splitting the disjunction into its components and associating each component with a branch of a UNION ALL query.

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;

可能更糟

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