max(col)需要索引?

时间:2011-02-10 14:12:56

标签: performance oracle statistics indexing

我目前正在为一种仓库解决方案进行一些数据加载。我每晚都从生产中获取数据,然后必须加载。仓库表没有其他更新。要仅为某个表加载新项目,我目前正在执行以下步骤:

  • 获取特定列的当前最大值y(日记帐表的id和事件表的时间)
  • 通过where x > y
  • 等查询加载数据

为了避免性能问题(我每天加载大约100万行),我从表中删除了大多数索引(只需要生产,而不是仓库)。但是这样检索最大值需要一些时间......所以我的问题是:

获取该列没有索引的列的当前最大值的最佳方法是什么?我刚刚阅读了关于使用stats但我不知道如何处理带有'timestamp with timezone'的列。在加载之前禁用索引,并在之后重新创建索引需要太长时间......

4 个答案:

答案 0 :(得分:3)

作为列级统计信息的一部分计算的最小值和最大值是估算值。优化器只需要它们合理地靠近,而不是完全准确。我当然不会相信它们是加载过程的一部分。

每天加载一百万行并不是特别多。你有一个非常小的负载窗口?我有点难以相信您无法承担索引最小/最大索引扫描所需行的成本。

但是,如果要避免使用索引,则可能需要将最后一个最大值存储在作为加载过程一部分维护的单独表中。在表A中加载行1-1000后,您将更新此汇总表中表A的行,以指示您处理的最后一行是行1000.下一次,您将读取该值中的值汇总表并从1001开始。

答案 1 :(得分:2)

如果列上没有索引,则DBMS在列中找到最大值的唯一方法是完整的表扫描,这对于大型表需要很长时间。

我认为DBMS可以尝试跟踪列中的最小值和最大值(存储系统目录中的值),因为它会插入,更新和删除 - 但删除是我没有尝试过DBMS的原因。使每行操作保持最新统计信息。如果删除最大值,如果未对列进行索引,则查找新的最大值需要进行表扫描(如果对其进行索引,则索引会使得查找最大值变得微不足道,因此信息不必存储在系统目录)。这就是为什么他们被称为'统计';它们是适用的值的近似值。但是当你要求'SELECT MAX(somecol)FROM sometable'时,你并没有要求统计最大值;你问的是实际的当前最大值。

答案 2 :(得分:0)

让创建提取文件的进程还提取具有所需最小/最大值的单行文件。我假设该片段是在某些cron或scheduler上编写的,所以不应该过多地要求将min / max计算添加到该脚本中;)

如果没有,只需进行全面扫描即可。特别是在数据仓库环境中,百万行并不多。

答案 3 :(得分:0)

此代码是用oracle编写的,但应与大多数SQL版本兼容:

根据范围得到表中max(high_val)的关键字。

select high_val, my_key
from (select high_val, my_key
      from mytable
      where something = 'avalue'
      order by high_val desc)
where rownum <= 1

这就是说:对于某些值='avalue'的值,以high_val降序排序mytable。只抓住顶行,它将为您提供所选范围内的max(high_val)和该表的my_key。