我有一个包含 2 个外键的表。我是 MySQL 的新手,谁能告诉我将索引应用于表的正确方法是什么?
# Sample 1
CREATE TABLE IF NOT EXISTS `my_table` (
`topic_id` INT UNSIGNED NOT NULL ,
`course_id` INT UNSIGNED NOT NULL ,
PRIMARY KEY (`topic_id`, `course_id`) ,
INDEX `topic_id_idx` (`topic_id` ASC) ,
INDEX `course_id_idx` (`course_id` ASC) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
# Sample 2
CREATE TABLE IF NOT EXISTS `my_table` (
`topic_id` INT UNSIGNED NOT NULL ,
`course_id` INT UNSIGNED NOT NULL ,
PRIMARY KEY (`topic_id`, `course_id`) ,
INDEX `topic_id_idx` (`topic_id`, `course_id`) ,
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
我想我真正想问的是将两者定义为单独的索引和将另一个定义为组合的索引之间有什么区别?
最佳答案
您可能想要其中之一而不是另一个的原因与您计划查询数据的方式有关。做出正确的决定可能需要一点技巧。
考虑组合键,例如,在文件柜中查找学生的文件夹,首先按学生的姓氏,然后按他们的名字。
现在,对于您的示例中的两个单一索引,您可以想象,在学生示例中,有两组不同的有组织的文件夹,一个按顺序排列每个名字,另一个按顺序排列姓氏.在这种情况下,您将始终需要处理最大数量的相似记录,但如果您只有一个名字或另一个名字,这就无关紧要了。在这种情况下,这种安排为您提供了最大的灵 active ,同时仍然只维护两列的索引。
相比之下,如果同时给出名字和姓氏,那么对于我们人类来说,首先按姓氏查找学生会容易得多,然后再按名字查找(在较小的潜在集合中)。然而,当姓氏未知时,很难仅通过名字找到学生,因为具有相同名字的学生可能与姓氏的每个版本交错(表扫描)。计算机用来查找信息的算法也是如此。
因此,根据经验,如果您要同时按两个值过滤数据,请将额外的键添加到单个索引。如果有时您只有一个而不是另一个,请确保哪个值是索引中最左边的键。如果值可能是其中之一,那么您可能需要两个索引(其中一个索引实际上可能同时具有两个关键字中最好的两个关键字,但即使这样也会在写入方面付出代价)。正确处理这些事情可能非常重要,因为这通常相当于一场全有或全无的游戏。如果 dbms 执行索引查找所需的所有数据都不存在,它可能会求助于表扫描。 Mysql 的 explain
功能是一种有助于检查配置和识别优化的工具。
关于mysql - 将 INDEX 应用于外键的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12048602/