我面临以下问题,我不确定什么是最佳实践。
考虑下表(该表会变大):
id PK | Giver_id FK | FK | 日期
我正在使用InnoDB,据我了解,它会自动为两个外键列创建索引。但是,在需要匹配以下特定组合的情况下,我还会做很多查询:
SELECT...WHERE giver_id = x AND recipient_id = t
。
每个这样的组合在表中将是唯一的。
在这些列上添加双列索引有什么好处,还是理论上两个单独的索引足够/相同?
我面临以下问题,我不确定什么是最佳实践。
考虑下表(该表会变大):
id PK | Giver_id FK | FK | 日期
我正在使用InnoDB,据我了解,它会自动为两个外键列创建索引。但是,在需要匹配以下特定组合的情况下,我还会做很多查询:
SELECT...WHERE giver_id = x AND recipient_id = t
。
每个这样的组合在表中将是唯一的。
在这些列上添加双列索引有什么好处,还是理论上两个单独的索引足够/相同?
Answers:
如果您有两个单列索引,那么在您的示例中将只使用其中一个。
如果您有一个包含两列的索引,则查询可能会更快(应该进行测量)。两列索引也可以用作单列索引,但仅适用于首先列出的列。
有时在(A,B)上有一个索引,在(B)上有另一个索引可能会很有用。这使得使用任一列或两列的查询都很快,但是当然也使用了更多的磁盘空间。
选择索引时,还需要考虑对插入,删除和更新的影响。更多索引=更新速度较慢。
覆盖指数如下:
ALTER TABLE your_table ADD INDEX (giver_id, recipient_id);
...将意味着如果查询中提到的索引可以使用giver_id
,或组合giver_id
和recipient_id
。请注意,索引标准是基于最左侧的-仅引用的查询recipient_id
将无法使用我提供的语句中的覆盖索引。
另外,MySQL每个SELECT只能使用一个索引,因此覆盖索引将是优化查询的最佳方法。
MySQL can only use one index per SELECT
这不再是事实,如果您编辑了要更新的答案,那就太好了。
recipient_id
吗?
INDEX (col1, col2, col3, col4)
则该索引将用于带有WHERE
诸如col1 = 'A'
或col1 = 'A' AND col2 = 'B'
或的子句的搜索col1 = 'A' AND col2 ='B' AND col3 = 'C' AND col4 = 'D'
,但是该特定索引将不用于诸如WHERE col2 = 'B'
或的任何东西,WHERE col3 = 'C' AND col4 = 'D'
因为搜索字段在索引定义中没有保留最多。您将不得不添加其他索引来覆盖这些字段。
如果外键索引之一已经具有很高的选择性,那么数据库引擎应将那个用于您指定的查询。大多数数据库引擎使用某种启发式方法能够在那种情况下选择最佳索引。如果两个索引本身都不是高度选择性的,那么添加基于两个键构建的索引可能确实有意义,因为您说您将大量使用该类型的查询。
要考虑的另一件事是,是否可以消除此表中的PK字段并在giver_id
和recipient_id
字段上定义主键索引。您说组合是唯一的,因此可能会起作用(鉴于许多其他条件,只有您可以回答)。不过,通常来说,我认为增加的复杂性不值得麻烦。