Sql 查询时,索引表是否比非索引表快?

Sql 查询时,索引表是否比非索引表快?,sql,database,Sql,Database,假设我们有两个相同的表,有数百万行,它们有业务事务,两个表都有完全相同的信息。一列指定行是“销售”还是“订单”,其他列指定名称(通常重复)、日期、金额、税费等 表中的数据没有组织,因此显然销售和订单以及其他数据没有以任何方式进行排序 唯一的区别是其中一个表有一个具有唯一主键的额外列 如果我使用不涉及主键的相同WHERE子句查询具有相同查询的表。一些可能涉及以下内容的查询:WHERE action=“sale”和name=“Bob Smith” 对于havix索引,其中一个会比另一个更快吗???如

假设我们有两个相同的表,有数百万行,它们有业务事务,两个表都有完全相同的信息。一列指定行是“销售”还是“订单”,其他列指定名称(通常重复)、日期、金额、税费等

表中的数据没有组织,因此显然销售和订单以及其他数据没有以任何方式进行排序

唯一的区别是其中一个表有一个具有唯一主键的额外列

如果我使用不涉及主键的相同WHERE子句查询具有相同查询的表。一些可能涉及以下内容的查询:WHERE action=“sale”和name=“Bob Smith”


对于havix索引,其中一个会比另一个更快吗???

如果在查询的Where部分使用的字段上对表进行索引,则索引表会更快


Mysql参考解释了这一点。

当您在没有索引的列上使用条件进行查询时,理论上,无论是否存在PK,您都应该获得几乎相同的性能。然而,在实践中,它取决于RDMS实现。根据我的经验,我可以肯定地说,在SQLServer中,当查询堆表(没有集群键的表)时,您会看到总体性能更差,Oracle处理堆的性能要好得多,我希望也有相同的性能

索引表有一个额外的字段,它占用磁盘空间

您对查询的描述可以通过以下两种方式之一得到满足。假设表中没有
where
子句中列的索引。在这种情况下,查询将进行完整的表扫描。因此,主键的额外空间是一个问题。比如说,该记录中的每条记录比另一条记录长4字节。通常,这会增加需要读取的表的数量,并增加查询时间

您可以猜测,如果每个基本记录是100字节,那么每个带有主键的记录将是104字节,整个查询将长约4%(还有其他因素在起作用,但这提供了一个关于发生了什么的高级概念)

另一方面,如果存在满足
where
子句的索引,并且结果集比总体数据小得多,那么引擎将查找索引中的值,找到适当的页面并从页面中获取结果。在这种情况下,每次获取大约读取一个页面,因此这两个页面的性能应该是相似的


综上所述,我强烈支持表应该有一个唯一的自动递增主键的概念。

每个索引都是纯粹的冗余:

  • 存储空间成本
  • 占用原本可能被其他内容占用的缓存空间
  • 必须在插入/更新/删除时维护
如果查询可以使用索引,则加速通常远远超过上面列出的因素。相反,如果未使用索引,则该索引不应存在

但是,在试图删除索引及其上的键之前,请记住,如果数据不正确,性能并不重要。由于应用程序错误1,至少没有主键的表对重复行开放,不能充当外键的父端点,并且其行不能在客户端代码中合理标识

或者尝试识别一个已经“嵌入”到数据中的自然主键,或者至少创建一个(就像您在其中一个表中所做的那样)



1严格地说,这样的表甚至不表示关系,这不再是一个“关系”数据库。关系的数学概念是一个集合,而不是多集合,这意味着一个元素要么在集合中,要么不在集合中,但不能在集合中多次出现。

一个表有一个索引(主键),而另一个表根本没有索引?确切地说。其中一个表中只有1个索引主键,另一个表既没有索引也不唯一。我所做的查询根本不涉及主键。什么会使扫描堆表比扫描b树更糟糕?行仍然以有效的随机顺序进行搜索。至少堆可能没有那么零碎。这是一个诚实的问题,不是吹毛求疵的问题。@siride:据我所知,它需要更少的磁盘随机读取(当然,如果集群表不是很零碎的话)。顺序读取比随机读取便宜得多,即使大小相同。免责声明:这是我个人的经验和解释(我可能错了,但我在向表中添加集群代理键时遇到了问题[本质上是堆-没有什么是唯一的,也没有什么必须是唯一的]会产生显著的差异)。这发生在SQLServer2008R2中,可能是一些2012年不存在的bug;我还没有机会检查它,但是不管表的结构如何,它都会按顺序从磁盘读取数据吗?该查询将进行无序扫描,因此它可以从头到尾读取表,这可以有效地完成。@siride:是的,但问题是(同样,我认为)SQLServer中堆表中的行可以存储在任何物理位置,从表的开始到结束读取表可能需要更多的头来回移动。当涉及到索引组织的表(或聚集的,无论我们想使用什么术语),引擎都会尝试或多或少地按顺序存储它们。这就是,对于具有主键的表,其中一个是它唯一的索引列,其他列没有索引,并且在任何方面都不是唯一的,并且在向表中插入数据时没有顺序。