Quantcast
Channel: Forum SQL Server Database Engine
Viewing all articles
Browse latest Browse all 15889

Query plan with TOP clause causes query to fail

$
0
0

My database is SQL 2008 R2. I have a query look like below.

create table #t (MsgRunId varchar(10) primary key, MsgCode varchar(5));
insert into #t
	(MsgRunId, MsgCode)
values
	('Ax100', 'Ax'),
	('Ax99', 'Ax'),
	('Bah120', 'Bah'),
	('Bah99', 'Bah');
select * from #t where MsgCode = 'Ax' order by cast(substring(MsgRunId, 3, len(MsgRunId) - 2) as int) desc;
--with r
--as
--(
--	select *
--	from #t
--	where MsgCode = 'Ax'
--)
--select top 2 * from r
--order by cast(substring(MsgRunId, 3, len(MsgRunId) - 2) as int) desc;
drop table #t;

The intention is to get the latest message for a particular MsgCode. Since MsgRunId is of type varchar, simply sort by MsgRunId will not retrieve the latest record. For example, Ax99 will be greater than Ax100. So I extract the numeric part from the MsgRunId and sort by it. Since MsgCodes have different length, so the where clause to filter for a particular MsgCode is important because substring won't work for all MsgCode.

Please note the above script is to illustrate the intension only.

I ran the same query in different SQL instances, all with same Server edition and table schema. Only difference is number of records in each environment. What I encountered is in one environment the query runs successfully, while in the other is failed. The error message shows that the query fetches a record with a different MsgCode than I specified in where clause and after substring it contains alphabet part in addition to digits and causes the cast to INT to fail.

Both single query and CTE failed in the failed instance. To make it work, I have to create a temp table first.

The query plan for successful instance looks like.

select <- top <- parallelism <- sort(top N sort) <- compute scalar <- clustered index scan

The query plan for failed instance looks like.

select <- top <- filter <- sort <- compute scalar <- clustered index scan

In both query plans, the compute scalar step creates the expession used in the order by clause.

However, in the successful quey plan, the filtering of MsgCode happens in the first step of clustered index scan. For the failed query plan, the filtering happens in the filter step, and no wonder the query failed becuase it just took all records for all MsgCode before compute scalar.

I do not want to comment how SQL query optimiser chooses a query plan. My question is whether this is the correct case that a query plan chosen by SQL query optimiser could cause a query to fail. Shouldn't query optimzation guarantee the correctness of the logic of query plan in the first place?



Viewing all articles
Browse latest Browse all 15889

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>