将INDEX应用于外键的正确方法

时间:2012-08-21 04:52:05

标签: mysql sql indexing

我有一张包含2个外键的表。我对MySQL有点新手,有人能告诉我将INDEX应用于表格的正确方法吗?

# 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;

我想我真正要问的是将两者定义为单独的索引而将另一个定义为合并后的区别是什么?

2 个答案:

答案 0 :(得分:1)

您可能希望其中一个优于另一个的原因与您计划查询数据的方式有关。正确地做出这个决定可能会有点诡计。

考虑组合密钥,例如,在文件柜中查找学生的文件夹,首先是学生的姓氏,然后是他们的名字。

现在,在您的示例中有两个单个索引的情况下,您可以想象,在学生示例中,有两组不同的有组织文件夹,一个按顺序排列每个名字,另一个按姓氏排序。 。在这种情况下,您将始终必须处理大量类似的记录,但如果您只有一个名称或另一个名称,则无关紧要。在这种情况下,这种安排可以为您提供最大的灵活性,同时仍然只保留两列的索引。

相比之下,如果给出名字和姓氏,那么我们作为人类首先按姓氏查找学生,然后按名字(在较小的潜力范围内)查找更容易。但是,当姓氏不知道时,单独使用名字就很难找到学生,因为具有相同名字的学生可能会与姓氏的每个部分(表扫描)交错。计算机用于查找信息的算法也是如此。

因此,根据经验,如果您要同时按两个值过滤数据,请将额外的键添加到单个索引。如果有时你会有一个而不是另一个,请确保它是哪个值,它是索引中最左边的键。如果值可能是,那么你可能想要两个索引(其中一个索引实际上可以同时拥有两个词中最好的两个词的键,但即使这样也需要写入成本)。获得这些东西是非常重要的,因为这通常相当于一个全有或全无的游戏。如果dbms需要执行索引查找所需的所有数据,则可能需要进行表扫描。 Mysql的explain功能是一个有助于检查配置和识别优化的工具。

答案 1 :(得分:0)

如果您使用一个密钥创建索引,那么在搜索数据时,它将仅通过该密钥找到。

 INDEX `topic_id_idx` (`topic_id` ASC) ,

 INDEX `course_id_idx` (`course_id` ASC) 

在这种情况下,数据分别搜索topic_id和course_id。但是如果你把它们组合在一起就会结合起来搜索数据。

例如,如果您有如下数据:

topic_id       course_id

----------

abc               1
pqr               2
abc               3

如果要搜索abc - 3,如果你放置单独的索引,那么它将分别搜索这两列并找到结果。 但是如果你把它们组合起来,它就会直接搜索abc + 3.

相关问题