具有时间戳的mysql数据库中时间序列的最佳索引策略

时间:2014-02-28 17:31:23

标签: mysql performance indexing time-series

我有一个数据库,我正在处理包含脉冲测量的数据 架构是这样的:

id - monitorid - starttime - stoptime - pulses

每个监视器每10分钟提供一次信息 目前,这相当于大约13 000 000行。

开始和停止时间是varchar(10),保存unix时间戳。对我来说可能效率不高。

几乎所有针对此表的查询都是'WHERE starttime> $ certaintime AND monitorid = $ monid'。所有这些查询目前都非常缓慢。

我有一个关于monitorid的索引。我还没有把它放在开始时间和停止时间上,因为我认为这会给我带来更好的基数,因为每10分钟的时间段是一个新值。我不确定这个推理。

所以,我的问题是:如何针对大多数面临的类似范围的查询优化此问题。索引启动时间?使用日期而不是时间戳重建表?

欢迎任何建议!

干杯,

迪特

1 个答案:

答案 0 :(得分:6)

monitorid + starttime列上创建复合btree索引 对于使用WHERE starttime > X AND monitorid = Y子句

的查询,此索引可以提供最佳结果
CREATE INDEX name ON tablename( monitorid + starttime )

monitorid必须是此索引中的前导列,否则索引将无法使用 有关详细信息,请阅读“8.2.1.3.2多部分索引的范围访问方法”一章:https://dev.mysql.com/doc/refman/5.7/en/range-optimization.html

他们写道:

  

对于BTREE索引,区间可以用于与AND组合的条件,其中每个条件使用=,< =>,IS NULL,>,<,>来比较具有常数值的关键部分。 =,< =,!=,<>,BETWEEN或LIKE'pattern'(其中'pattern'不以通配符开头)。只要可以确定包含与条件匹配的所有行的单个密钥元组(或者如果使用<>或!=,则为两个间隔),可以使用间隔。

     

只要比较运算符为=,< =>或IS NULL,优化程序就会尝试使用其他关键部分来确定区间。如果运算符是>,<,> =,< =,!=,<>,BETWEEN或LIKE,优化程序将使用它,但不再考虑关键部分。对于以下表达式,优化器使用=来自第一次比较。它还使用了来自第二次比较的> =,但没有考虑其他关键部分,也没有使用第三个比较进行区间构建:

     

key_part1 ='foo'和 key_part2 > = 10 AND key_part3 > 10

(强调我的)

上面的意思是,在您的特定情况下,如果将创建monitorid + starttime上的索引,那么opimizec可以使用索引的两个部分,因为monitorid = $monid在where子句中使用,但是在反向索引顺序starttime + monitorid,索引的第二部分不可用,因为在where子句中使用了starttime > $certaintime