用于连接表的最佳SQL索引(Best SQL indexes for join table)

2019-07-29 14:28发布

考虑到性能方面的改进,我想知道是否和索引是基于连接表(在Rails 3 has_and_belongs_to_many文中特别使用)有帮助。

型号和表安装

我的模型是FooBar ,每个Rails约定,我有一个连接表称为bars_foos 。 没有主键或时间戳使得该表中的老油田bar_id:integerfoo_id:integer 。 我想知道以下哪些指标是最好的,是没有重复:

  1. 的化合物索引: add_index :bars_foos, [:bar_id, :foo_id]
    • 两个指标
    • A. add_index :bars_foos, :bar_id
    • B. add_index :bars_foos, :foo_id
  2. 两个图1和2-B的组合

基本上,我不知道,如果复合索引是足够假设它是有帮助的开始。 我相信,一个复合索引可以被用作这就是为什么我肯定,使用这三种线肯定会导致不必要的重复的第一个项目的单一指标。

可能的使用

最常见的用法将给予模型的实例Foo ,我会要求其关联的bars使用的回报率语法foo.bars ,反之亦然bar.foos为模型的实例Bar

这会产生类型的查询SELECT * FROM bars_foos WHERE foo_id = ?SELECT * FROM bars_foos WHERE bar_id = ? 分别,然后使用那些得到的ID来SELECT * FROM bars WHERE ID in (?)SELECT * FROM foos WHERE ID in (?)

请纠正我的意见,如果我是不正确的,但我不相信,在Rails应用程序的情况下,这是以往任何时候都尝试做一个查询它指定既像的ID SELECT * FROM bars_foos where bar_id = ? AND foo_id = ? SELECT * FROM bars_foos where bar_id = ? AND foo_id = ?

数据库

倘若有数据库特定的优化技术,我将最有可能使用PostgreSQL。 然而,其他人使用此代码可能想用它在MySQL或SQLite的取决于其Rails的配置,以便所有的答案是赞赏。

Answer 1:

答案

人们经常重复的答案,这往往总是这样的情况往往不是就是,“看情况”。 更具体地讲,它取决于你的数据是什么,以及它如何被使用。

TL;博士解释

短TL;对于我的具体情况医生的回答(和覆盖所有未来的基地)是首选#2这就是我怀疑。 然而,选择#3会工作得很好,因为根据我的数据的使用,用于创建复合索引可以减少未来的查询查找额外的时间和空间。

充分说明

这样做的原因是,数据库自作聪明,并尝试做的事情尽可能快无论程序员的输入。 最基本的项目时要考虑添加索引是将这个对象通过此键进行查找。 如果是的话,指数有可能帮助加快这件事。 不过,该指数是否甚至被用来说来说去选择性和外地的基数。

由于外键通常是另一个AR类的ID,通常基数会很高。 但同样,这取决于你的数据。 在我的例子,如果有很多Foo秒,但一些Bar S,很多在我的连接表项将有simliar bar_id秒。 随着bar_id小号具有低基数,在索引bar_id可能永远不会被使用,也可以顺便通过使数据库投入时间和资源*每一个新的时间加入到这个指数越来越bars_foos项创建。 这同样有许多Bar S和几个Foo S和几两的。

一般的经验是,考虑在表上的索引时,决定是否参赛作品将被同时望向了这个领域,如果这个领域具有较高的基数。 也就是说,它这个领域有许多独特的价值? 在大多数的情况下连接表“这取决于”我们必须更仔细地想想该数据表示和关系本身。 就我而言,我将同时拥有许多Foo S和Bar S和将查找Foo通过其相连的S bar S和反之亦然。

另外一个很好的答案,我在办公室得到的是,“为什么你担心你的索引?建立你的应用程序!”

脚注

*在类似的问题上STI指数有人指出,索引的成本是非常低的,所以当有疑问,只需添加它。



Answer 2:

取决于你如何去查询数据。

假设你要搜索所有这些...

  • WHERE bar_id = ?
  • WHERE foo_id = ?
  • WHERE bar_id = ? AND foo_id = ?

......那么你或许应该对指数走{bar_id, foo_id}和索引{foo_id}

虽然你也可以创建第三个指数{bar_id} ,维护额外的指数的价格可能会超过更好的效益聚集在小的索引。


还有,你怎么打算支付使用索引的查询? 一些替代品,如...

  • {foo_id, bar_id}{bar_id}
  • {foo_id, bar_id}{bar_id, foo_id}

...可能包括某些类型的查询更好的。

覆盖是一个平衡的行为 - 有时加入索引的字段只用于覆盖的目的是有道理的,有时不是。 你不会知道,直到你衡量现实的数据。

(免责声明:我不熟悉的红宝石这个答案纯粹是从数据库的观点。)



文章来源: Best SQL indexes for join table