【问题标题】:Indexing on foreign keys外键索引
【发布时间】:2020-01-29 22:36:45
【问题描述】:

使用 MySQL。我有 2 个基本表儿童和组。两者都是直截了当的。孩子:身份证、名字、姓氏。组:id,名称。一个孩子可以在 0 到多个组中。一个组可以包含 0 到多个孩子。这在第三个表中处理:子组。我已为子项和组添加了外键。

CREATE TABLE childgroups 
(
    childId INT,
    groupId INT
);

ALTER TABLE childgroups 
    ADD FOREIGN KEY (fk_child) REFERENCES children(id);
ALTER TABLE childgroups 
    ADD FOREIGN KEY (fk_group) REFERENCES groups(id);

由于没有自动索引外键,我想在 childgroups 表上创建索引。

我将在这张桌子上使用如下语句:

SELECT childId 
FROM childgroups 
WHERE groupId = 123;

SELECT groupId 
FROM childgroups 
WHERE childId = 1366;

SELECT children.firstname, children.lastname 
FROM children, childgroups, groups 
WHERE groups.name = "Lions";

仅在 childId 和/或 groupId 上定义一个索引就足够了吗?

或者我是否也指定一个组合索引,例如:

CREATE INDEX childgroups_index ON childgroups (childid);
CREATE INDEX childgroups_index ON childgroups (groupid);
CREATE INDEX childgroups_index ON childgroups (childid, grouppid);

【问题讨论】:

  • 索引是高度特定于供应商的 - 所以请添加一个标签来指定您使用的是mysqlpostgresqlsql-serveroracle 还是db2 - 或完全不同的东西。

标签: mysql performance indexing foreign-keys


【解决方案1】:

您关于外键不会自动索引的假设是不正确的,请参阅Using FOREIGN KEY Constraints

MySQL 需要外键和引用键的索引,以便外键检查可以快速且不需要表扫描。在引用表中,必须有一个索引,其中外键列按相同顺序列为第一列。 如果引用表不存在,则会自动在其上创建此类索引。 如果您创建另一个可用于强制外键约束的索引,则稍后可能会静默删除此索引。 index_name,如果给定,如前所述使用。

但是,您的表缺少(childId, groupId) 上的唯一键,否则,您可以多次添加相同的组合。因此,最好将这两列设为(复合)主键(这对于关联表很常见):

CREATE TABLE childgroups 
(
    childId INT,
    groupId INT,
    primary key (childId, groupId)
);

除了groupId上的外键生成的隐式索引(childId上的外键可以使用主键),你能想到的每一个索引要求都满足了,不需要加该表上的任何其他索引。

【讨论】:

  • 在一个非常老的 MySQL 版本中,我记得你必须自己创建索引才能定义外键。不过,这已经有很多年了。
  • 我在某处读到外键没有索引,但也许那是针对另一个 SQL 服务器平台的,您提供的文档很清楚!主键的提示也是一个非常优雅的解决方案。顶!
猜你喜欢
  • 2010-11-01
  • 2012-02-13
  • 2015-05-12
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多