|
|
1
6
不,绝对不是。这里有两个因素在起作用。
在您的情况下,以及涉及布尔或的任何其他情况下,最好将@AuthorType移到查询之外:
下一个最好的方法是使用UNIONALL,正如chadhoc已经建议的那样,在视图或其他需要一条语句的地方(如果允许的话,则不使用),这是正确的方法。 |
|
|
2
4
这是由于优化器处理“或”类型逻辑以及 issues 与 parameter sniffing . 尝试将上面的查询更改为文章中提到的联合方法 here . i、 e.您将得到多个语句,它们联合在一起,只有一个@AuthorType=x,并允许优化器排除和逻辑与给定@AuthorType不匹配的部分,然后依次查找适当的索引。。。看起来像这样:
|
|
|
3
0
SELECT ... lots of columns and complicated stuff ...
FROM
(
SELECT MyPK
FROM TBooks
WHERE
(--...SOME CONDITIONS)
AND @AuthorType = 1 AND --...DIFFERENT CONDITIONS)
union all
SELECT MyPK
FROM TBooks
WHERE
(--...SOME CONDITIONS)
AND @AuthorType = 2 AND --...DIFFERENT CONDITIONS)
union all
...
) AS B1
JOIN TBooks AS B2
ON B2.MyPK = B1.MyPK
JOIN ... other tables ...
伪表B1只是获取PKs的WHERE子句。然后将其连接回原始表(以及任何其他需要的表)以获得“演示”。这样可以避免在每个UNION ALL中重复显示列
我们对非常大的表执行此操作,其中用户可以选择查询什么。 DECLARE @MyTempTable TABLE
(
MyPK int NOT NULL,
PRIMARY KEY
(
MyPK
)
)
IF @LastName IS NOT NULL
BEGIN
INSERT INTO @MyTempTable
(
MyPK
)
SELECT MyPK
FROM MyNamesTable
WHERE LastName = @LastName -- Lets say we have an efficient index for this
END
ELSE
IF @Country IS NOT NULL
BEGIN
INSERT INTO @MyTempTable
(
MyPK
)
SELECT MyPK
FROM MyNamesTable
WHERE Country = @Country -- Got an index on this one too
END
... etc
SELECT ... presentation columns
FROM @MyTempTable AS T
JOIN MyNamesTable AS N
ON N.MyPK = T.MyPK -- a PK join, V. efficient
JOIN ... other tables ...
ON ....
WHERE (@LastName IS NULL OR Lastname @LastName)
AND (@Country IS NULL OR Country @Country)
请注意,所有测试都是重复的[从技术上讲,您不需要@Lastname one:)],包括(比方说)不在原始过滤器中创建@mytentable的模糊测试。
缩放问题?回顾正在进行的实际查询,并添加可以改进的案例。 |
|
John D · 需要为NULL或NOT NULL的WHERE子句 1 年前 |
|
Marc Guillot · 记录值时忽略冲突 1 年前 |
|
|
Fachry Dzaky · 正确使用ROW_NUMBER 1 年前 |
|
|
TriumphTruth · 从满足特定条件的数据集中选择1行 1 年前 |