用于排序功能的合适索引

时间:2010-10-12 11:22:26

标签: sql-server sql-server-2005 query-optimization

我有一个表保持项目之间的父子关系。这些可以随着时间的推移而改变,有必要保留完整的历史记录,以便我可以随时查询关系。

表格是这样的(我删除了一些列和主键等以减少噪音):

CREATE TABLE [tblRelation](
    [dtCreated] [datetime] NOT NULL,
    [uidNode] [uniqueidentifier] NOT NULL,
    [uidParentNode] [uniqueidentifier] NOT NULL
)

我在特定时间获取关系的查询是这样的(假设@dt是具有所需日期的日期时间):

SELECT *
  FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY r.uidNode ORDER BY r.dtCreated DESC) ix, r.*
      FROM [tblRelation] r
      WHERE (r.dtCreated < @dt)
    ) r
  WHERE r.ix = 1

此查询效果很好。但是,性能还不如我想的那么好。在查看执行计划时,它基本上归结为聚集索引扫描(成本的36%)和排序(成本的63%)。

我应该使用哪些索引来加快查询速度?或者是否有更好的方法在此表上执行此查询?

2 个答案:

答案 0 :(得分:3)

此查询的理想索引是使用键列uidNodedtCreated,并在表中包含列,以便在返回r.*时使索引覆盖。如果查询通常只返回相对较少的行(看起来可能是由于WHERE r.ix = 1过滤器),那么可能不值得使索引覆盖,因为密钥查找的成本可能不会超过负数大索引对CUD语句的影响。

答案 1 :(得分:1)

SQL Server 2005上的窗口/排名函数有时不是最优的(基于此处的答案)。在SQL Server 2008中显然更好

另一种选择是这样的。我在(uidNode,dtCreated)上有一个非聚集索引INCLUDE SELECT所需的任何其他列。取决于马丁史密斯所说的查找。

WITH MaxPerUid AS
(
    SELECT
       MAX(r.dtCreated) AS MAXdtCreated, r.uidNode
    FROM
       MaxPerUid
    WHERE
       r.dtCreated < @dt
    GROUP BY
       r.uidNode
)
SELECT
    ...
FROM
   MaxPerUid M
   JOIN
   MaxPerUid R ON M.uidNode = R.uidNode AND M.MAXdtCreated = R.dtCreated