2

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

表中的数据没有组织,因此很明显 Sales 和 Orders 以及其他数据没有以任何方式排序。

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

如果我使用不涉及主键的相同 WHERE 子句查询具有相同查询的表。一些涉及的查询可能像:WHERE action = "sale" and name = "Bob Smith"

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

4

4 回答 4

7

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

  • 花费存储空间,
  • 占用可能被其他东西占用的缓存空间
  • 必须在 INSERT/UPDATE/DELETE 上维护。

如果查询可以使用索引,则加速通常大大超过上面列出的因素。相反,如果不使用索引,则它不应该存在。

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

要么尝试识别已经“嵌入”在数据中的自然主键,要么至少制作一个代理键(就像您在其中一个表中所做的那样)。


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

于 2013-06-08T22:46:22.773 回答
1

索引表有一个占用磁盘空间的附加字段。

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

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

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

尽管如此,我强烈支持表应该具有唯一的自动递增主键的概念。

于 2013-06-08T22:13:13.000 回答
1

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

于 2013-06-08T21:56:46.450 回答
0

如果表在您用于查询的 Where 部分的字段上建立索引,则索引表会快得多。

Mysql Reference在这里解释它。

于 2013-06-08T21:53:55.883 回答