【问题标题】:Group Indexing in InformixInformix 中的组索引
【发布时间】:2012-12-13 10:47:59
【问题描述】:

我有一个名为hitlist 的表,它有 3 列:

int id
long hitlisted_date
long deleted_date

我将根据这些列查询此表:

histlisted_date (frequent)
hitlisted_date && deleted_date (frequent)
deleted_date (not frequent)

在这种情况下,我应该使用什么样的索引?

  1. hitlisted_date & deleted_date 上的单独索引
  2. hitlisted_datedeleted_date 上的组索引

更新

该表将只有 1000 - 5000 行。
这些是将要使用的查询模式。

1) hitlisted_date BETWEEN
2) hitlisted_date 3) deleted_date = -1 和 hitlisted_date 4) 删除日期 > 0

对于上述模式,这些索引就足够了吗?

  1. 在 hitlist(hitlisted_date) 上创建索引 i1_hitlist;
  2. CREATE INDEX i2_hitlist ON hitlist(deleted_date, hitlisted_date);

【问题讨论】:

  • 请注意,DATE(-1) 是 1899-12-30。如果一切都足够新以至于不会干扰,那没关系,但就在不久前,普遍流通的人比这更老。
  • 日期列是long数据类型(纪元时间)
  • 所以它们不是 DATE 类型。它们是 INTEGER 列。 Informix 中的 DATE 类型具有特定的含义。 (而且 1969-12-31 23:59:59 比 1899-12-30 更新;即使这样也可能不是问题,但要小心。)
  • 看起来您需要将 LONG 时期转换为 DATETIME 或 DATE 类型列才能正确执行日期算术查询。

标签: indexing informix


【解决方案1】:

由于hitlisted_date 和组合会被频繁使用,因此您希望在两列上首先使用hitlisted_date 的复合索引:

CREATE INDEX i1_hitlist ON hitlist(hitlisted_date, deleted_date);

此索引可以(并且将)用于在 hitlisted_date 上单独或两个日期具有合适条件的查询。

您可能会发现仅在 deleted_date 上创建第二个索引是有益的:

CREATE INDEX i2_hitlist ON hitlist(deleted_date);

这仅可用于搜索 deleted_date。如果您有时在单个删除日期和一系列命中列表日期上进行搜索,那么您可能会发现使用与 i1_hitlist 相反的复合索引会更好:

CREATE INDEX i2_hitlist ON hitlist(deleted_date, hitlisted_date);

这不太可能有帮助,但唯一确定的方法是尝试并查看。这取决于您的查询模式以及您的查询使用的实际条件。

hitlisted_date 的索引并没有真正的优点;它只是妨碍了优化器(因为它必须查看两个索引并决定哪个更好,并且因为在插入、更新和删除行时还有更多工作要做)。命中列表日期不太可能是唯一索引。如果可以,那么保留单列索引和重复索引将有一个单独的原因。 (另见Is an index on (A,B) redundant if there is an index on (A, B, C)。)

更改索引后,确保统计信息是最新的(这些天或多或少是自动的,但它曾经很重要),然后使用 SET EXPLAIN 运行查询以检查索引是否正在使用(以及正在使用哪些索引)。

【讨论】:

  • 那么为什么不只在 (A,B,C) 上创建一个复合索引呢?这应该涵盖任何查询组合?
  • 在交叉引用的问题中,(A,B,C)上已经有索引;问题是仅 (A, B) 的索引是否也有益。答案是“不,除非 (A, B) 是唯一的”。
  • 几个因素:列基数、频繁查询模式、nrows、行长、静态或频繁表更新等决定如何以及哪些列要索引?
  • @JonathanLeffler 我已经根据您的输入更新了我的问题,其中包含有关表格和索引的一些信息。让我知道它是否看起来不错。索引是否会为所有 4 种查询模式提供服务?
  • 它在“灰色范围”内。如果表少于 100 行,那么索引可能不值得麻烦。如果该表在数百万行中,那么它们将是值得的。如果表是数千个,那么索引很有可能是有益的。要考虑的一种选择是将id 作为索引中的第三列。然后查询引擎可以使用仅索引搜索,而不必读取索引和数据页。 (对于一个小表且没有索引,您将在一个或两个页面上进行顺序扫描,这比读取索引页面和数据页面要快。)
【解决方案2】:
CREATE CLUSTER INDEX clusidx ON hitlist(hitlisted_date,deleted_date);
CREATE         INDEX ddatidx ON hitlist(deleted_date);

如果表的行数很少,甚至可能不值得对列进行索引,但如果行数很多,则可以。由于您在此表中只有 3 列,因此索引不会成为大量行的问题。

例子:

我有一个包含 13 个 VARCHAR 列和 2 个 DATE 列的静态只读表。

行长度 = 557,nrows = 12,398,250。

索引 7 个单独的列,因为没有涉及多列的频繁查询,但如果经常查询一个特定的列组合,则为这些查询创建一个复合列索引。

【讨论】:

  • hdaidx 不会付出代价。
  • 是的;集群索引可用于 hdaidx 可用于的任何事情。如果对于任何给定的命中列表日期,将有大量的删除日期,那么有时使用单列索引可能会更好,但它是有益的,这将是相当不寻常的。如果表是动态的(大量活动),那么额外的索引在更新时可能会比在选择时节省的成本更高;如果表几乎是静态的(活动很少),那么情况可能正好相反。命中列表日期不太可能是唯一索引;如果可以,可能还有其他原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
相关资源
最近更新 更多