我查询了以下表格:
SELECT * FROM MyTable WHERE Timestamp > [SomeTime] AND Timestamp < [SomeOtherTime]
我想优化这个查询,我正在考虑在时间戳上放一个索引,但我不确定这是否会有所帮助。理想情况下,我想使时间戳成为聚簇索引,但MySQL不支持聚簇索引,主键除外。
MyTable
有400万行。Timestamp
实际上是INT
类型。Timestamp
的行数平均约为20,但可能高达200。Timestamp
大于现有的大多数行,但可能会少于一些较新的行。 Timestamp
上的索引会帮助我优化此查询吗?
答案 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)
我不同意索引改进选择查询时间的重要性,但如果您可以索引其他键(并使用这些索引形成查询),则可能不需要索引时间戳。
例如,如果您的表格包含timestamp
,category
和userId
,则最好在userId
上创建索引。在具有许多不同用户的表中,这将大大减少搜索时间戳的剩余集合。
...如果我没有弄错,这样做的好处是可以避免在每次插入时创建时间戳索引的开销 - 在具有高插入率和高度唯一时间戳的表中,这可能是一个重要的考虑因素。
我正在努力解决基于时间戳和其他键的索引问题。我仍然有测试这样做,我可以证明我在这里说的话。我会尝试根据我的结果进行回发。
更好解释的方案:
类别25%唯一
**对不起,我不知道计算的开销或插入索引。