光标延迟结果集,如何使其高效

时间:2012-08-06 15:15:44

标签: sql sql-server sql-server-2008 cursor

我有一个包含数据的表变量:

SiteID  DatabaseYear  CreationDate
1       2011          2012.01.01
2       2012          2012.06.06
3       2010          2010.10.10
1       2012          2012.07.07
3       2012          2012.07.27
4       2012          2012.08.31

在一个完美的世界里,我想对结果进行排序:

SiteID  DatabaseYear  CreationDate
4       2012          2012.08.31
3       2012          2012.07.27
3       2010          2010.10.10
1       2012          2012.07.07
1       2011          2012.01.01
2       2012          2012.06.06

排序如下:获取具有最新创建日期的网站并首先显示它(按CreationDate desc排序),然后获取该网站的所有其他记录并通过DatabaseYear显示它们(按DatabaseYear desc排序)。

当然,以下内容根本不起作用:

order by CreationDate desc, DatabaseYear desc

因为它将首先在整个结果集上应用“CreationDate desc”,然后再应用“DatabaseYear desc”。

所以,我想出了一个执行以下操作的游标:

  1. 获取最新的SiteID
  2. 把它放在另一个表中(确切地说是表变量)
  3. 获取该SiteID的所有其他记录,按DatabaseYear降序排列
  4. 从第一张表中删除所有记录
  5. 问题:

    如果第一个表有几千个记录,这个逻辑很有效,但是当有超过5000个记录时,那么它需要更长的时间。由于这是在网页上填充网格,我不能让用户等待超过15-20秒。在最糟糕的情况下(超过40,000条记录),执行需要2-3分钟。

    任何建议都将受到赞赏。

2 个答案:

答案 0 :(得分:2)

你需要在集合方面考虑更多,游标几乎永远正确的答案。你似乎更像是一个强制性的程序员。

这可以比最初出现的更简单:

WITH Most_Recent_Site (siteId, createdOn) as (SELECT id, MAX(createdOn)
                                              FROM Site_Data
                                              GROUP BY id)

SELECT Site_Data.id, Site_Data.createdOn
FROM Site_Data
JOIN Most_Recent_Site
ON Most_Recent_Site.siteId = Site_Data.id
ORDER BY Most_Recent_Site.createdOn DESC, Site_Data.createdOn DESC

我故意遗漏了'数据库年'专栏,因为它似乎没有添加任何价值。

(我有一个工作SQL Fiddle example。)

答案 1 :(得分:1)

DECLARE @t TABLE  
(
  SiteID INT,  
  DatabaseYear INT,  
  CreationDate DATE
);

INSERT @t VALUES
(1,2011,'2012-01-01'),
(2,2012,'2012-06-06'),
(3,2010,'2010-10-10'),
(1,2012,'2012-07-07'),
(3,2012,'2012-07-27'),
(4,2012,'2012-08-31');

;WITH x AS 
(
  SELECT SiteID, d = MAX(CreationDate) 
     FROM @t
     GROUP BY SiteID
)
SELECT t.SiteID, t.DatabaseYear, t.CreationDate 
FROM @t AS t
INNER JOIN x 
ON t.SiteID = x.SiteID
ORDER BY x.d DESC, t.CreationDate DESC;