How can I force a subquery to perform as well as a #temp table?

后端 未结 4 2074
既然无缘
既然无缘 2020-12-17 08:21

I am re-iterating the question asked by Mongus Pong Why would using a temp table be faster than a nested query? which doesn\'t have an answer that works for me.

Mos

4条回答
  •  抹茶落季
    2020-12-17 09:10

    Having run into this problem, I found out that (in my case) SQL Server was evaluating the conditions in incorrect order, because I had an index that could be used (IDX_CreatedOn on TableFoo).

    SELECT bar.*
    FROM
        (SELECT * FROM TableFoo WHERE Deleted = 1) foo
        JOIN TableBar bar ON (bar.FooId = foo.Id)
    WHERE
    foo.CreatedOn > DATEADD(DAY, -7, GETUTCDATE())
    

    I managed to work around it by forcing the subquery to use another index (i.e. one that would be used when the subquery was executed without the parent query). In my case I switched to PK, which was meaningless for the query, but allowed the conditions from the subquery to be evaluated first.

    SELECT bar.*
    FROM
        (SELECT * FROM TableFoo WITH (INDEX([PK_Id]) WHERE Deleted = 1) foo
        JOIN TableBar bar ON (bar.FooId = foo.Id)
    WHERE
    foo.CreatedOn > DATEADD(DAY, -7, GETUTCDATE())
    

    Filtering by the Deleted column was really simple and filtering the few results by CreatedOn afterwards was even easier. I was able to figure it out by comparing the Actual Execution Plan of the subquery and the parent query.


    A more hacky solution (and not really recommended) is to force the subquery to get executed first by limiting the results using TOP, however this could lead to weird problems in the future if the results of the subquery exceed the limit (you could always set the limit to something ridiculous). Unfortunately TOP 100 PERCENT can't be used for this purpose since SQL Server just ignores it.

提交回复
热议问题