在时间戳上创建索引以优化查询

时间:2012-01-31 22:11:50

标签: mysql optimization indexing timestamp

我查询了以下表格:

SELECT * FROM MyTable WHERE Timestamp > [SomeTime] AND Timestamp < [SomeOtherTime]

我想优化这个查询,我正在考虑在时间戳上放一个索引,但我不确定这是否会有所帮助。理想情况下,我想使时间戳成为聚簇索引,但MySQL不支持聚簇索引,主键除外。

  • MyTable有400万行。
  • Timestamp实际上是INT类型。
  • 插入一行后,永远不会更改。
  • 任何给定Timestamp的行数平均约为20,但可能高达200。
  • 新插入的行的Timestamp大于现有的大多数行,但可能会少于一些较新的行。

Timestamp上的索引会帮助我优化此查询吗?

4 个答案:

答案 0 :(得分:45)

毫无疑问。如果没有索引,您的查询必须查看表中的每一行。使用索引,只要找到正确的行,查询就会非常即时。您支付的价格是轻微的插入效果;但那确实很轻微。

答案 1 :(得分:7)

你绝对应该使用索引。 MySQL不知道这些时间戳的顺序是什么,并且为了找到给定时间戳(或时间戳范围)的记录,它需要查看每个记录。有400万,这是相当多的时间!索引是告诉MySQL有关数据的方式 - “我会经常查看这个字段,所以请列出我可以找到每个值的记录的位置。”

对于定期查询的字段,索引通常是一个好主意。定义索引的唯一缺点是它们使用额外的存储空间,所以除非你真的很紧张,否则你应该尝试使用它们。如果它们不适用,MySQL无论如何都会忽略它们。

答案 2 :(得分:5)

如果您的查询主要使用此时间戳,则可以测试此设计(将时间戳作为第一部分放大主键):

CREATE TABLE perf (
  , ts INT NOT NULL
  , oldPK 
  , ... other columns 
, PRIMARY KEY(ts, oldPK)
, UNIQUE (oldPK)
) ENGINE=InnoDB ;

这将确保您发布的查询之类的查询将使用群集(主要)密钥。

缺点是你的插入会慢一点。此外,如果表上有其他索引,它们将使用更多的空间(因为它们将包括4字节更宽的主键)。

这种聚集索引的最大优点是具有大范围扫描的查询,例如必须读取表的大部分或整个表的查询将按顺序并按所需顺序(BY timestamp)查找相关行,如果要按天或按周或按月分组,这也很有用。年。

旧的PK仍可用于通过对其保持UNIQUE约束来识别行。


您可能还想查看允许TokuDB的MySQL(和开源)变体multiple clustered indices

答案 3 :(得分:4)

我不同意索引改进选择查询时间的重要性,但如果您可以索引其他键(并使用这些索引形成查询),则可能不需要索引时间戳。

例如,如果您的表格包含timestampcategoryuserId,则最好在userId上创建索引。在具有许多不同用户的表中,这将大大减少搜索时间戳的剩余集合。

...如果我没有弄错,这样做的好处是可以避免在每次插入时创建时间戳索引的开销 - 在具有高插入率和高度唯一时间戳的表中,这可能是一个重要的考虑因素。

我正在努力解决基于时间戳和其他键的索引问题。我仍然有测试这样做,我可以证明我在这里说的话。我会尝试根据我的结果进行回发。

更好解释的方案:

  1. 时间戳99%唯一
  2. userId 80%unique
  3. 类别25%唯一

    • 对时间戳进行索引会将查询结果快速减少到表格大小的1%
    • 对userId建立索引会将查询结果快速减少到表格大小的20%
    • 对类别建立索引会将查询结果快速减少到表格大小的75%
    • 在时间戳上插入索引会有很高的开销**
    • 尽管我们知道我们的插入会尊重增加时间戳的事实,但我没有看到任何基于增量键的MySQL优化的讨论。
    • 在userId上插入索引会有相当高的开销。
    • 在类别上插入索引会有相当低的开销。
  4. **对不起,我不知道计算的开销或插入索引。