Sql-server – Incorrect query results for execution plan, unsure of exact cause of problem

sql serversql-server-2012

We had a query yesterday that was intended to page through results but on the first page of results the query only returned 4 records instead of the expect 25. Changing the query in any way resulted in 25 records which meant to me that it was an execution plan issue. I'm not familiar with a way to view execution plan in production and running the query in sql studio didn't result in same problem, probably due to minor differences.

I read suggestions that such a thing could be caused by a corrupted index. I ran a checkdb on the database and it found no errors. In the end I cleared the execution plans and all has been well.

If it wasn't a corruption issue of some kind and only a problem for the very specific execution plan then does that mean there was simply an error in the execution plan and we are hitting a bug in SQL Server? We are on SQL Server 2012 RTM with no updates so I looked through documentation on all fixes in cumulative updates and service packs but none of the issues appeared to related to our own.

Any other ideas or thoughts as to what could cause this?

(@P1 varchar(8000),@P2 bit,@P3 varchar(8000),@P4 bit,@P5 varchar(8000))

SELECT e.*
FROM (

    SELECT 

        TOP 25
        ROW_NUMBER() OVER (
            ORDER BY AddedDate DESC
        ) AS Row,

        ID
        , Prefix
        , FirstName
        , LastName
        , Company
        , Address
        , City
        , State
        , Zip
        , Country
        , WorkPhone
        , HomePhone
        , MobilePhone
        , Email
        , MailingLists
        , AddedDate
        , AwaitingOptin
        , OptInDate
        , Processed
        , ProcessedDate
        , Deleted
        , Source
        , GRRecID
        , DatabaseID
        , (SELECT COUNT(*) 
            FROM TableA
            LEFT OUTER JOIN TableB ON TableA.GRRecID = TableB.GRRecID
            WHERE TableA.AccountID = @P1 
                AND TableA.Email = TableC.Email
                AND TableA.Deleted = @P2 
                ) AS Matches
    FROM TableC
    WHERE AccountID = @P3  
        AND Processed = @P4  
        AND Deleted = 0
        AND Source = @P5  
) AS e
WHERE Row >= 1 AND Row <= 25
ORDER BY Row

Best Answer

You should consider refactoring to use the new paging clause in SQL Server 2012, ( OFFSET...FETCH ), rather than that old-fashioned 'roll your own paging' eg

SELECT 
...
FROM TableC
WHERE AccountID = @P3
    AND Processed = @P4
    AND Deleted = 0
    AND Source = @P5  

ORDER BY ProcessedDate DESC
OFFSET 0 ROWS FETCH NEXT 25 ROWS ONLY

It's potentially more efficient. Here's a sample SQL Fiddle.