Home > Net >  Adding sort destroys simple SQL query
Adding sort destroys simple SQL query

Time:03-16

I have a fairly simple query that is supposed to return only a single number – the ID of the TOP record from the query. It is not especially elegant, but it works well, except for the Sort clause. When I select and execute all but the Sort clause, it executes instantly, but naturally does not return the proper first record. When I add the sort, it hangs. I have let it run around ten minutes while watching the task manager. It shows regular peaks of 100% CPU usage alternately on two of the server's four cores, but does not bog the machine in any noticeable fashion.

When I run just the inner part, it returns 6070 records. Sorting that and returning the first one should be a completely trivial task, but that is not the case. I can't even check the execution plan, because it never finishes, at least not in the amount of time I am willing to let it run.

What can be going wrong, that SQL Server cannot properly handle such a simple query?

declare @Taxonomie nvarchar(max) = '%rupicapra%'

SELECT Top 1 AkcesAutoID, PP.Rok, PP.AkcesitPred, PP.Akcesit
FROM (
    SELECT    
        P.AkcesAutoID, A.AkcesitPred, A.Akcesit, A.Rok    
    FROM dbo.Podrobnosti P    
    LEFT JOIN dbo.vwFirstSynonymika S ON P.PodrobnostiAutoID = S.PodrobnostiAutoID    
    INNER JOIN dbo.Akces A ON P.AkcesAutoID = A.AkcesAutoID    
    LEFT JOIN dbo.Taxonomy T ON P.TaxonAutoID = T.TaxonAutoID    
    WHERE (T.CompleteTaxonText Like @Taxonomie)    
) PP    
ORDER BY PP.Rok, PP.AkcesitPred, PP.Akcesit

CodePudding user response:

Does this get a better plan than the existing subquery? Post both to paste the plan and update the question with the table/index structure. This will more likely be fixed by adjusting indexes than changing the query.

declare @Taxonomie nvarchar(max) = N'%rupicapra%';
------ also important! ------------^

--  SELECT Top 1 AkcesAutoID, PP.Rok, PP.AkcesitPred, PP.Akcesit
--  FROM 
--  (
    SELECT P.AkcesAutoID, A.AkcesitPred, A.Akcesit, A.Rok    
      FROM dbo.Podrobnosti P    
      INNER JOIN dbo.Akces A 
        ON P.AkcesAutoID = A.AkcesAutoID
      WHERE EXISTS 
      (
        SELECT 1 FROM dbo.Taxonomy T 
          WHERE P.TaxonAutoID = T.TaxonAutoID 
          AND T.CompleteTaxonText Like @Taxonomie
      )    
--  ) PP    
--  ORDER BY PP.Rok, PP.AkcesitPred, PP.Akcesit

CodePudding user response:

Why an ORDER BY kills my query?

When you run the query without the ORDER BY, SQL Server only needs to find the first row that meets the JOIN and WHERE clauses. It does not care which row meets that condition, just that at least one row does, and it returns it. It stops scanning any additional rows at that point, and returns the single row.

However, when you add the ORDER BY, SQL Server must now read ALL data returned by your query into memory, not just the first row (or pages) that match. Then, it must sort all of that data before it knows which row will be the TOP 1.

This could be the difference or reading a few MB of data into memory, or many 100s of GB of data into memory. All depending on the size of your tables.

That is a high level reason of why ORDER BY often kills a query plan.

Adding your plans for both queries and any indexes that exists on the tables would be helpful to evaluate further. You can paste your plans at pastetheplan.com.

  • Related