我有一个带有列的表'数据' id(auto_increment)id_device(整数)时间戳(数字)
我需要执行这些选择:
select * from data where id<10000000 and id_device=345
or
select * from data where id<10000000 and id_device=345 and timestamp>'2017-01-01 10:00:00' and timestamp<'2017-03-01 08:00:00'
首先选择: 为“id”制作单独的索引并为“id_device”分开是否更好? 或者像INDEX id,id_device?
这样的索引更好第二次选择: 最好为“id”创建单独的索引并为“id_device”分隔并为“timestamp”分开? 或者像INDEX id,id_device,timestamp?
这样的索引更好答案 0 :(得分:1)
我的简短回答:这取决于您的数据。
更长:如果id_device = 345对于比id <10000000更少的行而为真,则应在多列索引中首先列出id_device:... ON data(id_device,id)。此外,如果选择速度对于您/您的用户比插入/更新/删除速度更重要,那么为什么不添加大量索引并将其留给查询计划器以选择要使用的索引:
create index i01_tbl on tbl(id);
create index i02_tbl on tbl(id_device);
create index i03_tbl on tbl(timestamp);
create index i04_tbl on tbl(id,id_device);
create index i05_tbl on tbl(id_device,id);
create index i06_tbl on tbl(timestamp,id);
create index i07_tbl on tbl(id,timestamp);
create index i08_tbl on tbl(id_device,timestamp);
create index i09_tbl on tbl(timestamp,id_device);
create index i10_tbl on tbl(id, id_device, timestamp);
create index i11_tbl on tbl(id_device, id, timestamp);
create index i12_tbl on tbl(id_device, timestamp, id);
create index i13_tbl on tbl(id, timestamp, id_device);
create index i14_tbl on tbl(timestamp, id_device, id);
create index i15_tbl on tbl(timestamp, id, id_device);
数据库中的查询计划程序算法(sqlite也有它们)通常会对此做出很好的选择。特别是如果您定期运行ANALYZE sqlite命令或更改大量数据后。拥有多个索引的缺点是插入和删除速度较慢(如果它们涉及索引列,则更新)以及更多的磁盘/内存使用量。对重要的SQL(在速度方面很重要)使用解释计划来检查使用和不使用的索引。如果从未使用索引或仅在没有它的情况下快速查询中使用索引,那么您可以删除它们。另请注意,您的数据库的新版本(sqlite,oracle,postgresql)可以使用更新的查询计划程序算法,这对于大多数SELECT更好,但对于某些人来说可能会变得更糟。对现实数据集进行真实的测试是最好的方法。要创建哪些索引并不是一门精确的科学,并且没有适合所有情况的明确规则。