问题
My query:
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
It executes in 30 seconds.
If I remove order by Id
section, it executes in 1 second.
Or if I remove one OR
condition, it also executes in 1 second.
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
Columns ModelId
and RegionId
has indexes. Id
is primary key.
Execution plan show that 97% clustered index searched for Id.
Please, help me. Why so slowly for 3 OR
condition with ORDER BY
?
回答1:
You could try to expand OR(from Oracle but idea is the same):
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;
回答2:
Might be worse
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
来源:https://stackoverflow.com/questions/49758239/sql-server-slow-query-with-3-or-condition-and-order-by-id