让我们说我们必须有2个相同的表,有数百万行,并且它们有业务事务,两个表都有完全相同的信息。一列指定行是“销售”还是“订单”,其他列指定名称(通常重复),日期,金额,税金等....
表中的数据没有组织,所以销售和订单以及其他数据都没有以任何方式排序。
唯一的区别是其中一个表有一个额外的列,它有唯一的主键。
如果我使用相同的查询查询具有相同WHERE子句但不涉及主键的表。一些涉及的查询可能类似于:WHERE action =“sale”和name =“Bob Smith”
其中一个是否会更快,另一个是havix索引?
答案 0 :(得分:6)
每个索引都是纯粹的冗余:
如果查询可以使用索引,则加速通常会大大超过上面列出的因素。相反,如果未使用索引,那么它就不应该存在。
但在尝试消除索引及其顶部的密钥之前,请记住,如果数据不正确,性能无关紧要。由于应用程序错误 1 ,没有至少主键的表格对重复的行是开放的,不能充当FOREIGN KEY的父端点,并且无法在客户端代码中合理地识别其行。
尝试识别已经“嵌入”数据的自然主键,或者至少制作一个surrogate key(正如您在其中一个表中所做的那样)。
1 严格来说,这样的表甚至不代表关系,这不再是“关系型”数据库。关系的数学概念是一个集合,而不是多集合,意味着元素在集合中或不在集合中,但不能多次出现在集合中。
答案 1 :(得分:1)
当您在没有索引的列上查询条件时,理论上无论是否存在PK,您都应该获得相同的性能。但是,实际上它取决于RDMS的实现。根据我的经验,我可以肯定地说,在SQLServer中,当查询堆表(没有集群密钥的表)时,你会发现整体性能更差,Oracle处理堆更好,我期望性能相同。
答案 2 :(得分:1)
索引表有一个占用磁盘空间的附加字段。
您可以通过以下两种方式之一来满足您对查询的描述。假设表中没有where
子句中的列的索引。在这种情况下,查询将执行全表扫描。然后,主键的额外空间是个问题。例如,每条记录在该记录中比在另一条记录中长4个字节。通常,这会增加需要读取的表的数量,并增加查询的时间。
您可以猜测,如果每个基本记录是100个字节,则每个具有主键的记录将是104个字节,并且整个查询将长约4%(还有其他因素在起作用,但这会产生高级别发生了什么的想法。)
另一方面,如果存在满足where
子句和的索引,则结果集远远小于整体数据,那么引擎将查找值索引,找到适当的页面并从页面中获取结果。在这种情况下,每次获取大约会有一页读取,因此两者的性能应该相似。
所有这一切,我强烈支持表格应该具有唯一的自动递增主键的概念。
答案 3 :(得分:0)
如果表在您用于查询的Where部分的字段上编制索引,则索引表将快得多。
Mysql Reference解释了它here。