我有一些关于是否最好不使用索引的问题。
背景: 我的记录有一个时间戳属性,记录将按时间戳的顺序插入(即按时间顺序插入)。
问题:
如果我不使用索引,数据库是否按照插入顺序插入记录?
如果对#1的回答是肯定的,当我执行“SELECT .. WHERE timestamp> X”类型查询时,数据库会对它有效,或者它是否必须遍历每一条记录,因为它没有编入索引?我假设如果没有索引,数据库就不会“知道”记录是按排序顺序插入的,因此不能使用数据库的sorted属性。
我认为聚集索引最适合这些类型的记录&他们的插页。
请让我知道你们的想法。
谢谢, JBU
答案 0 :(得分:3)
根据我的经验,是的,数据库将按时间顺序插入内容,特别是如果您从未删除任何内容。但是,这并不能保证,尝试依赖无法保证的行为是一个非常糟糕的主意。
此外,查询计划程序不会知道这一事实,因此您在没有索引的情况下执行的任何查询都将导致全表扫描。这是否比索引查询慢,将在很大程度上取决于您拥有的数据类型,以及查询中“X”后的数据百分比。
答案 1 :(得分:1)
当然,这取决于您使用的数据库!
一般来说,如果你要做很多插入,最好是禁用索引,插入,然后重新创建索引
使用时间戳作为聚簇索引(即存储行的顺序)仅在最常见的查询按时间顺序排列时(与检索此行相反)并且如果没有重复的时间戳
答案 2 :(得分:1)
如果表中从未删除任何删除,则可以假设数据库只是将新块添加到表的末尾。但是,无法保证磁盘上的这些块是连续的,还是正确推进(即表可能会随着时间的推移而分段)。
没有索引的表中的任何SELECT都将导致表扫描。索引是指如何“告诉”数据库“时间戳按升序排列”等内容。
聚簇索引适用于告知数据库要在表中保持索引顺序的行。但是,它通常(取决于您的实现)仅对合理的静态数据有价值,因为这是DB确保表的行确实按索引顺序的唯一方式,因为它通过重建表来实现。
答案 3 :(得分:1)
什么数据库?
1)
没有索引的表称为堆。堆将按插入顺序存储记录。只要你不从多个线程插入,你就能够预测数据库存储记录的顺序。正如其他人所指出的那样,这确实假设你没有做删除,在这种情况下你的DBMS可能会用新行填充空白页面。
2)
如果没有索引,DBMS将不得不进行完整的表扫描(相对于记录数以线性时间运行)。对于插入时间戳增加的记录的记录,聚簇索引会很好。只要您不插入旧时间戳,因此DBMS必须根据聚簇索引在物理上重新排列行。
答案 4 :(得分:1)
聚簇索引是磁盘上记录的顺序。无论你是否指定一个,都会有一个,因为磁盘上必须有一个订单。
主键也是聚簇索引是正常的,但不一定是这种情况。
如果您正在进行批量插入,则可能会插入具有相同时间戳的多个记录。显然,这不能成为主键。
为了进行“SELECT .. WHERE timestamp> X”之类的查询,“timestamp”字段上的索引将提高该查询的性能,无论它是否为群集。
“timestamp”字段上的索引是否应该是群集的,以及是否还需要其他索引将取决于您需要对数据执行的所有查询。
答案 5 :(得分:0)
我是jbu,后期创作者。
感谢大家的快速投入。
要解决更多问题:
是的我有静态数据 - 我不会删除。
我正在测试几个不同的数据库:Sybase SQL Anywhere,Oracle Berkeley DB,H2,Firebird,SQLite以及其他一些数据库。
Steven Lowe:我的桌子将有数百万条记录(最多会增加到32GB)。如果我关闭索引一段时间,然后重新创建索引,这不会花费很长时间 - 至少几分钟(我会认为它可能需要更长时间)?另外,我认为你假设连续的插入流会中断。我将几乎不断地使用批量插入提交插入,所以我不认为我的CPU和磁盘真的有一个休息时间来重建索引。
再次感谢投票人员。
JBU
答案 6 :(得分:0)
这是典型的,但任何具体的实施,AFAIK都无法保证。因此,依靠它是不明智的。查询优化器也不依赖于它,因此它将进行表扫描。
您案例中时间戳的聚集索引确实没有缺点。您可以填充100%的数据页面,并且您仍然不会比堆更糟糕。然而,查询可以利用它,并且可以从边缘(如果你返回,例如,表的90%)略微可笑(如果你正在返回,例如,表的1%)更快
答案 7 :(得分:0)
我相信根据sql标准,您永远无法确定在非有序列中选择行的顺序。即使您测试给定的数据库并且发现它当前是真的,也可能不是数据库的下一个版本的情况。我的经验是Steven Lowe的。如果要在表中插入大量行,请在插入之前禁用(或删除)行。插入后重新创建索引所花费的时间比带索引的插入时间短。
艾伦
答案 8 :(得分:0)
您需要在timestamp列上创建一个索引才能搜索我的时间戳。 Just Do It(TM)。
只有在按主键搜索时,聚簇索引才能帮助您。您可以将时间戳作为主键来利用它。