【问题标题】:Special case of Equi JoinEqui Join的特例
【发布时间】:2011-05-09 12:05:27
【问题描述】:

我遇到了这个特殊的脚本,它使用了一种特殊的 equi join 形式。

SELECT * 
FROM 
per_assignments a, per_assigment_types b
WHERE
a.assignment_status_type_id + 0  = b.assignment_status_type_id

为什么在 equi 连接中加了零?我开始知道这与避免索引搜索有关,但仍然有人可以解释它的全貌。提前致谢

编辑:

这与表/列声明无关。据我所知,这与 SQL 调优有关。

这是我发现的:-

  1. 这用于较小的表。
  2. 不是像往常那样进行索引搜索,而是一次性搜索整个表。

但我真的不知道与普通等值连接有什么区别,此外索引如何影响性能。

如果有人可以在特定上下文中进行描述,并且如果我的发现有误,请告诉我,这将非常有帮助。感谢您为此付出的时间和精力:-)

列说明

两个表中的赋值状态类型 ID 均声明为 NUMBER(9)

【问题讨论】:

  • 请提供您的表格声明(至少针对相关字段)
  • 我更新了,都声明为NUMBER(9)

标签: mysql sql plsql sql-tuning


【解决方案1】:

杀死小表的索引使用的原因是性能。当您使用索引执行连接时,需要两个磁盘 I/O 来读取数据。一是读取索引,二是从全表中读取数据。对于较小的表,读取整个表并执行全表扫描比执行第二个磁盘 I/O 更快。

这是一个广泛的概括,即使在您的数据库中也可能会不时发生变化。从理论上讲,SQL 优化器应该足够聪明,能够识别这种情况,并在没有提示的情况下对索引查找使用全表扫描。如果您将数据添加到一个或两个表中,也有可能将更快的性能从全表扫描转移到索引查找。

我对调整这些查询的疑问是:

  1. 表的精确定义是什么,包括 VARCHAR 列(如果有)的平均填充量是多少?
  2. 每个表有多少行?
  3. 每个表每天添加多少行?
  4. 此查询多久执行一次?
  5. 有没有人用这两个选项定时查询执行以查看哪个更快?

我担心这个查询被编写为一种巧妙的性能增强,无论是针对早期版本的数据库,还是仅仅作为一个聪明的 hack,而没有意识到查询优化器可能会做得更好或更好。

【讨论】:

  • 谢谢托马斯,真是个好发现。我真的不知道磁盘 I/O 部分,如果可能的话,你介意分享一个相同的链接/参考吗?谢谢。
  • 使用 +0 而不是 NO_INDEX 提示使这看起来更像是货物崇拜编程,而不是聪明的 hack。此外,您可能希望查看 Richard Foote 撰写的这些文章,这些文章解释了对于非常小的表,索引如何比全表扫描更好:en.wordpress.com/tag/small-indexes 基本上,一个非常小的索引(或索引组织的表)可以放在与并且比全表扫描需要更少的开销。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
  • 2018-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多