查询优化不首先执行内部查询

时间:2018-02-08 23:21:22

标签: sql sql-server tsql

运行此查询时:

create table #test (field varchar(100))

insert into #test (field) values ('this is not a number')
insert into #test (field) values ('1234567')

select  *
from    (   select  field
            from    #test
            where   ISNUMERIC(field) = 1
        ) as subquery
where   CAST(field as int) > 100

drop table #test

我期待返回1234567,但请改为:

Msg 245, Level 16, State 1, Line 7
Conversion failed when converting the varchar value 'this is not a number' to data type int.

内部查询不会先执行,而查询优化程序会对我尝试做的事情做出(不正确的)假设。我不得不用临时表解决这个问题:

create table #test (field varchar(100))

insert into #test (field) values ('this is not a number')
insert into #test (field) values ('1234567')

select  field
into    #subquery
from    #test
where   ISNUMERIC(field) = 1

select  *
from    #subquery
where   CAST(field as int) > 100

drop table #subquery
drop table #test

这是SQL查询优化器中的错误吗?任何人都可以向我解释这个吗?

编辑:回答这个问题是重复的...我没有使用' IN'声明。我写的逻辑意味着我需要在应用CAST条件之前返回已过滤的子查询。任何理智的人都希望我的查询以这种方式表现。优化者的查询版本显然在逻辑上不相同。

1 个答案:

答案 0 :(得分:3)

SQL Server优化器将命令(t-sql)作为输入,查看可用资源(索引,统计信息等)并提出最佳可能的计划,它考虑查询。这包括首先执行查询/部分查询,哪些谓词更深入查询等等。

因此,如果查看此查询的执行计划,谓词就会被推送到子查询中,因此转换为int失败。

执行计划中只有一个运算符,即表扫描,两个谓词都传递给内部查询。

如果你考虑一下,那么为什么从子查询中返回的行多于所需的,只有被外部查询中的where子句过滤掉才有意义。我不认为这是一个错误,而是一种优化执行计划的聪明方法:)

enter image description here