0

I'm on this site every day, but I've never posted before. I'm having the hardest time understanding why my query is taking so long.

Because SQL Server doesn't support returning a range of rows, we've had to get pretty fancy, so we're using a

SELECT FROM 
    (SELECT ROW_NUMBER() AS rownum...) 
WHERE rownum BETWEEN foo AND bar] 

statement.

The inner select returns ~13,000 rows in < 1 second (run separately). One of the columns returned is a SUM() from a joined table.

The outer select takes approximately 14 seconds to return the inner select values with a range of 500 - 1000. However, if I comment out the returned SUM, it takes < 1 second - which is what I would expect.

My question is, why does just the act of returning that SUM in the outer query take so long?

Examples below

Example full query (~14 seconds):

SELECT yadayada, number
FROM (SELECT yadayada, SUM(innerNum) AS number, 
          ROW_NUMBER() OVER (ORDER BY yadayada DESC) AS rownum
      FROM table1
      JOIN table2 ON table1.id = table2.id
      GROUP BY yadayada)
WHERE rownum BETWEEN 500 AND 1000

Example inner query (< 1 second):

SELECT yadayada, SUM(innerNum) AS number, 
          ROW_NUMBER() OVER (ORDER BY yadayada DESC) AS rownum
FROM table1
JOIN table2 ON table1.id = table2.id
GROUP BY yadayada

Example full query w/o returned SUM (< 1 second):

SELECT yadayada --, number (commented out, still returned in inner query)
FROM (SELECT yadayada, SUM(innerNum) AS number, 
          ROW_NUMBER() OVER (ORDER BY yadayada DESC) AS rownum
      FROM table1
      JOIN table2 ON table1.id = table2.id
      GROUP BY yadayada)
WHERE rownum BETWEEN 500 AND 1000
4

2 回答 2

1

我将冒险进行两个猜测,这可能会解释这个问题。

首先,当您测量内部子查询时,您是测量第一行出现之前的时间还是整个结果集出现之前的时间?我的猜测是你在看第一行。

我的第二个猜测是你有一个关于 yadayada 和 id 的索引。这意味着子查询只能使用索引来满足。当您包含附加列 innerNum 时,查询引擎实际上必须从其中一个表中读取页面。

因此,整个查询的开销是两件事的组合:

  • 需要返回完整的结果集
  • 需要访问原始表中的页面

我可能完全离开了,但这可能会给你一些关于可能导致问题的想法。二

于 2012-08-17T14:18:54.350 回答
0
Just try this:

;WITH CTE as 
(
SELECT yadayada, SUM(innerNum) AS number, 
          ROW_NUMBER() OVER (ORDER BY yadayada DESC) AS rownum
      FROM table1
      JOIN table2 ON table1.id = table2.id
      GROUP BY yadayada
)

select yadayada, number from CTE where rownum between 500 and 1000
于 2012-08-17T14:12:58.597 回答