通过索引优化SELECT

时间:2011-05-19 20:49:38

标签: sql informix indexing

我有一个大约7M行(并且正在计数)的大表。我正在尝试优化SELECT以尽可能快。 SELECT来自单个表,没有连接。数据库是IBM Informix。 SELECT速度是优先级,但表中插入的数量非常恒定。

WHERE中有23个参数,但我已将日期和语言确定为值得索引的参数:

...
WHERE (? >= valid_from OR valid_from IS NULL)
AND (? <= valid_to OR valid_to IS NULL)
AND ((? >= date_from AND ? <= date_to) OR (? >= date_from AND ? <= date_to)) 
AND language = ?
...

现在,在那上创建索引的最佳方法是什么?

  1. 我是否从valid_from,valid_to,date_from,date_to和language创建单独的索引?或者我创建三个复合索引(valid_from,valid_to),(date_from,date_to)和语言?或者我用五个创建一个大的复合索引?所有字段都是必填字段。

  2. 被比较日期的索引是一个好主意,还是我应该仅限于那些使用=(完全匹配)的字段?

  3. 如果复合索引是这样的话,我想复合索引中字段的顺序很重要 - 如何在索引中对列进行排序?列date_from和date_to会给我最大的第一次减少,但是语言可能会让我更快地减少(虽然这是假设我凭空消失 - 见问题2)。

  4. 如果有多个索引,Informix是使用所有索引还是只使用一个(以及哪一个)?

  5. 我的测试显示WHERE中的条件顺序并不重要,但我可能错了 - 是吗?

  6. WHERE中的某些条件是作为集合的列。 Informix不允许我索引这些列。这是否意味着这些条件与顺序扫描相匹配?将它们移到单独的表并加入它们是否合理有效?

  7. 到目前为止我做了什么:

    • 显然,没有连接,这是一个非规范化的表。我正在为这个插入更多的行付费,这对我很好,因为更新不是时间敏感的。
    • 我使用非常大的Informix扩展区来避免碎片,而pagesize则为我的表提供了最佳结果。

3 个答案:

答案 0 :(得分:1)

我也不知道Informix;你将不得不测试。 Postgres非常聪明,可以根据需要以明显的方式单独对变量进行单独的索引扫描,并且估计(并不总是那么好)这种方法是否优于表扫描。但是,我怀疑复合5列索引在这里运行良好。

我有另一个建议:使用默认值将日期的NULL值设置为无限极值;那么你没有特殊情况下的NULL。此外,这可能正确捕获业务逻辑。

如果两个?代表相同的参数,您可以使用(? >= date_from AND ? <= date_to)略微简化? IS BETWEEN date_from and date_to。只是语法糖,不会影响查询计划。

答案 1 :(得分:1)

您的和/或逻辑可能会使任何优化器对尝试创建有用的索引感到非常不满。

但是,您可以在Informix中创建功能索引,请参阅http://www.ibm.com/developerworks/data/library/techarticle/dm-0712wilcox/index.html。因此,对于这种方法,您可以创建用户定义的函数,以便您可以编写:

...
WHERE ? >= null_small_date(valid_from)
  AND ? <= null_large_date(valid_to)
  AND language = ?
  // hack, hack.  These 4 values should be the same as, but in a different order from
  // the next line .  This sanity check will let the index skip many possible records.
  AND max_date(?, ?) >= date_from AND min_date(?, ?) <= date_to
  AND ((? >= date_from AND ? <= date_to) OR (? >= date_from AND ? <= date_to)) 
  ...

考虑到这一点,您可以在(null_small_date(valid_from), null_large_date(valid_to), language, date_from, date_to)上创建单个连锁索引,这样您就可以跳过大部分结果,只关注表格的一小部分。

答案 2 :(得分:1)

我还有一个人不知道Informix,所以这在黑暗中有点像。根据各列的选择性,您可能只能索引其中的一个或两个以实现所需的性能。

更新统计数据值得验证。它看起来也像Informix支持查询提示:

http://www.ibm.com/developerworks/data/zones/informix/library/techarticle/0502fan/0502fan.html

允许您准确指定要使用的索引。