4

我已经在 SQL Server 中完成了这个显然没有优化的视图:

SELECT     ID, T_ID, SRNB, P_DATETIME,
                      (SELECT     TOP (1) COL_A
                        FROM          dbo.T_DETAIL AS T
                        WHERE      (T_ID = a.T_ID) AND (COL_A IS NOT NULL) AND (P_DATETIME <= a.P_DATETIME)
                        ORDER BY P_DATETIME DESC) AS COL_A, COL_A_MU,
                      (SELECT     TOP (1) COL_B
                        FROM          dbo.T_DETAIL AS T
                        WHERE      (T_ID = a.T_ID) AND (COL_B IS NOT NULL) AND (P_DATETIME <= a.P_DATETIME)
                        ORDER BY P_DATETIME DESC) AS COL_B, COL_B_MU,
--...for several columns
                      (SELECT     TOP (1) COL_Z
                        FROM          dbo.T_DETAIL AS T
                        WHERE      (T_ID = a.T_ID) AND (COL_Z > 0) AND (P_DATETIME <= a.P_DATETIME)
                        ORDER BY P_DATETIME DESC) AS COL_Z
FROM         dbo.T_DETAIL AS a

此视图的目的是从表 T_DETAIL 中获取最新的值 NOT NULL(或在某些情况下为 NOT 0)。

示例:T_DETAIL 是

+-----+------+------+----------------+-------+-------+-------+
| ID  | T_ID | SRNB |   P_DATETIME   | COL_A | COL_B | COL_Z |
+-----+------+------+----------------+-------+-------+-------+
| xxx | aaa  | aaa  | 20131205 20:15 | 5     | NULL  | 10    |
| xxx | aaa  | aaa  | 20131205 20:16 | NULL  | 10    | NULL  |
| xxx | aaa  | aaa  | 20131205 20:17 | NULL  | 5     | 5     |
| xxx | aaa  | aaa  | 20131205 20:18 | 5     | NULL  | NULL  |
| xxx | aaa  | aaa  | 20131205 20:19 | NULL  | NULL  | 11    |
| xxx | aaa  | aaa  | 20131205 20:20 | 7     | NULL  | 10    |
+-----+------+------+----------------+-------+-------+-------+

在视图中变成了这样:

+-----+------+------+----------------+-------+-------+-------+
| ID  | T_ID | SRNB |   P_DATETIME   | COL_A | COL_B | COL_Z |
+-----+------+------+----------------+-------+-------+-------+
| xxx | aaa  | aaa  | 20131205 20:15 | 5     | NULL  | 10    |
| xxx | aaa  | aaa  | 20131205 20:16 | 5     | 10    | 10    |
| xxx | aaa  | aaa  | 20131205 20:17 | 5     | 5     | 5     |
| xxx | aaa  | aaa  | 20131205 20:18 | 5     | 5     | 5     |
| xxx | aaa  | aaa  | 20131205 20:19 | 5     | 5     | 11    |
| xxx | aaa  | aaa  | 20131205 20:20 | 7     | 5     | 10    |
+-----+------+------+----------------+-------+-------+-------+

该视图有效,但速度非常缓慢。我应该从哪里开始优化它?我试图使它成为一个索引视图,但 SQL Server 管理器警告我,ORDER BY它仅用于TOP 1检索最新值。我想我应该从那开始,但是怎么做呢?也许MAX()在某个地方使用会是一个更好的选择,但我不想增加复杂性并搞砸事情。

我应该走什么路?是否有一种规范的方式来实现我正在寻找的东西?

4

2 回答 2

1

对于每个COL_X子查询,而不是:

(SELECT     TOP (1) COL_A
 FROM          dbo.T_DETAIL AS T
 WHERE      (T_ID = a.T_ID) AND (COL_A IS NOT NULL) AND (P_DATETIME <= a.P_DATETIME)
 ORDER BY P_DATETIME DESC) AS COL_A, COL_A_MU

尝试这个:

  (SELECT     COL_A
   FROM       dbo.T_DETAIL AS T
   WHERE      T_ID = a.T_ID
   AND        P_DATETIME =    
     (select  max(P_DATETIME) 
      FROM    dbo.T_DETAIL AS T2
      WHERE   T_ID = a.T_ID AND COL_A IS NOT NULL
      AND     P_DATETIME <= a.P_DATETIME
     )
   ) AS COL_A, 

我无法测试它,但我希望这会有所帮助。

为了获得更好的性能,在同一索引中T_ID(以及其他键列,如果它们在连接中使用)可能会有所帮助。P_DATETIME

于 2013-11-13T22:19:06.373 回答
0

“最近的值”

是否可以引入一个日期时间列(具有默认值)来存储创建的日期时间?

如果是,则可以使用此日期时间(试用其排序顺序)创建索引以进行快速“最近值”排序,然后在索引中跟随 ABZ 列。并在您的查询中使用此索引

于 2013-11-13T05:41:05.910 回答