我面临以下问题,我不确定最佳做法是什么。
考虑下表(会变大):
id PK | giver_id FK | recipient_id FK |日期
我正在使用InnoDB,根据我的理解,它会自动为两个外键列创建索引。但是,我还会在需要匹配特定组合的地方进行大量查询:
SELECT...WHERE giver_id = x AND recipient_id = t
。
每个这样的组合在表格中都是独一无二的。
在这些列上添加两列索引是否有任何好处,或理论上两个单独的索引是否足够/相同?
答案 0 :(得分:108)
如果您有两个单列索引,则在您的示例中只会使用其中一个索引。
如果您有一个包含两列的索引,则查询可能会更快(您应该测量)。两列索引也可以用作单列索引,但仅适用于首先列出的列。
有时在(A,B)上有索引,在(B)上有另一个索引。这使得查询快速使用其中一个或两个列,但当然也使用更多的磁盘空间。
选择索引时,还需要考虑插入,删除和更新的影响。更多索引=更新速度更慢。
答案 1 :(得分:24)
覆盖索引如:
ALTER TABLE your_table ADD INDEX (giver_id, recipient_id);
...意味着如果查询引用giver_id
或giver_id
和recipient_id
的组合,则可以使用该索引。请注意,索引条件是最左边的 - 只引用recipient_id
的查询无法在我提供的语句中使用覆盖索引。
此外,MySQL每个SELECT只能使用一个索引,因此覆盖索引将是优化查询的最佳方法。
答案 2 :(得分:4)
如果其中一个外键索引已经非常有选择性,那么数据库引擎应该使用该索引来指定您指定的查询。大多数数据库引擎使用某种启发式方法来在这种情况下选择最佳索引。如果这两个索引本身都不是高度选择性的,那么添加构建在两个键上的索引可能是有意义的,因为你说你会经常使用那种类型的查询。
另一件需要考虑的事情是,如果您可以删除此表中的PK字段,并在giver_id
和recipient_id
字段上定义主键索引。你说组合是独一无二的,所以可能会有效(给出很多其他条件,只有你可以回答)。但通常情况下,我认为增加的复杂性不值得麻烦。
答案 3 :(得分:1)
要考虑的另一件事是两种方法的性能特征将基于数据集的大小和基数。您可能会发现2列索引仅在某个数据集大小阈值时才会注意到更高的性能,或者恰好相反。没有什么可以替代您的确切方案的性能指标。