【发布时间】:2018-08-02 20:43:22
【问题描述】:
我在理解某些运算符优先级时遇到了一些困难,我预计下面的 所有 查询都会失败;这是基于下面的文档,其中将在比较运算符之前评估除法。
t-sql 运算符优先级的 Microsoft 文档:https://docs.microsoft.com/en-us/sql/t-sql/language-elements/operator-precedence-transact-sql?view=sql-server-2017
示例数据和查询
CREATE TABLE #orders(
price INT
)
GO
INSERT INTO #orders VALUES
(1)
,(2)
,(3)
,(4)
,(5)
,(6)
,(7)
,(8)
,(9)
,(10)
,(0)
GO
/*
the following two queries work
*/
SELECT *
FROM #orders
WHERE 2 / price > 0
AND price > 0;
SELECT *
FROM #orders
WHERE price > 0
AND 2 / price > 0;
/*
these don't work - getting divide by zero error
*/
SELECT *
FROM #orders
WHERE 2 / price > 0
AND price IN ( 1, 2, 3, 4,
5, 6, 7, 8,
9, 10 );
SELECT *
FROM #orders
WHERE price IN ( 1, 2, 3, 4,
5, 6, 7, 8,
9, 10 )
AND 2 / price > 0;
其中一个工作查询的共享执行计划:https://www.brentozar.com/pastetheplan/?id=HJFH3JWB7
其中一个非工作查询的共享(估计)执行计划:https://www.brentozar.com/pastetheplan/?id=r1Ds2yWSQ
任何帮助理解这种行为将不胜感激!
谢谢,
伊莱
【问题讨论】:
-
你可以用索引来防止,但很奇怪,对我来说看起来像一个错误。
-
@CetinBasoz 您能否详细说明索引将如何影响查询计划?
-
在#orders(价格)上创建非聚集索引ix_p;
-
@CetinBasoz 这是一个应该做的事情,虽然它没有解释为什么会这样。
-
当非聚集索引不比聚集索引更窄时,为什么优化器使用它?
标签: sql-server