需要从表中选择与最新版本匹配的版本列的行

时间:2012-01-13 20:36:30

标签: sql performance

在SQL中执行此操作的最佳方法是什么(Sybase SQL,如果区别很重要):

表格(包含一些示例数据)

| id | value1 | value2 | version |
==================================
| 1  | A11    | B11    | 1       | 
| 1  | A12    | B12    | 2       | 
| 2  | A21    | B21    | 1       | 
| 3  | A32    | B32    | 2       | 

Unique key: (id, version). Index: (id, version)
表中的

数据集大小: ~100k行,典型查询的where子句将结果限制为10-100个ID,版本#s为1,2或有时为3。

我需要做什么:每个ID,检索具有该ID最高版本的行

| id | value1 | value2 | version |
==================================
| 1  | A12    | B12    | 2       | <---- Chosen since 2>1 for id=1
| 2  | A21    | B21    | 1       | 
| 3  | A32    | B32    | 2       | 

简单的解决方案:我能想到的显而易见的方法是使用子查询:

SELECT  id, value1, value2
FROM    T   'T1'
WHERE   id in (1, 2, 3, ... 10)  -- Obviously a fake sample clause
 AND    version = (SELECT MAX(version) FROM T 'T2' 
                   WHERE T1.id=T2.id
                    AND  id in (1, 2, 3, ... 10)
                  )

问题:这是最好的方法吗?

“最好”在这里意味着:

  1. “平均效果最佳”(给定数据集大小,典型查询大小和上面显示的索引)。

  2. 对于具有类似性能的方法,最优雅的代码方式。这显然是旁观者的眼睛,但是如果你能证明代码更具可扩展性/可维护性,那么这就是优雅代码的明确标志。

2 个答案:

答案 0 :(得分:2)

SELECT *
FROM (
   SELECT id, 
          value1, 
          value2, 
          version,
          max(version) over (partition by id) as max_version
    FROM T
    WHERE id IN (1, 2, 3, ... 10)
) t2
WHERE version = max_version

根据您的DBMS(尤其是优化器)和索引,这可能比子选择更快,因为只需对表进行一次扫描。

答案 1 :(得分:0)

我认为使用JOIN而不是子查询会使其更具可读性:

SELECT  id, value1, value2
FROM    T   'T1'
INNER JOIN (
  SELECT id,MAX(version) as version 
  FROM T 
  WHERE id IN (...)
  GROUP BY id) T2
 ON (T1.id = T2.id AND T1.version=T2.version)
WHERE   T1.id in (1, 2, 3, ... 10)  

与原始查询相比,它不应导致任何性能开销/优势。