2016-08-30 89 views
0

我创建了两个具有一对多关系的表。Mysql索引不起作用

团队: -

CREATE TABLE TEAM(
    ID INT(5) NOT NULL AUTO_INCREMENT, 
    NAME VARCHAR(6) NOT NULL, 
    PRIMARY KEY(ID) 
)ENGINE=INNODB; 

会员: -

CREATE TABLE MEMBER (
    ID INT(5) NOT NULL AUTO_INCREMENT, 
    NAME VARCHAR(6) NOT NULL, 
    TEAM_ID INT(5) NOT NULL, 
    PRIMARY KEY (ID), 
    KEY TEAM_ID (TEAM_ID), 
    CONSTRAINT MEMBER_ibfk_1 FOREIGN KEY (TEAM_ID) REFERENCES TEAM (ID) 
) ENGINE=InnoDB 

一队可以有许多成员。

两个表内

数据: -

队表

ID NAME 
1 TEAM 1 
2 TEAM 2 

Member Table:- 

ID NAME TEAM_ID 
1 M1 1 
2 M2 1 
3 M3 1 
4 M4 1 
5 M5 1 
6 M6 1 
7 M7 1 
8 M8 1 
9 M9 2 
10 M10 2 
11 M11 2 
12 M12 2 

球队1是具有8名成员&小组2被具有4名成员。

现在我正在执行下面的加入查询来获取团队&成员的详细信息。

SELECT * FROM TEAM JOIN MEMBER ON TEAM.ID = MEMBER.TEAM_ID WHERE TEAM.ID = 1 

当我解释一个查询的计划时,我得到了下面的输出。

id select_type table type possible_keys key  key_len ref  rows   Extra 
1 SIMPLE  TEAM const PRIMARY   PRIMARY 4  const 1  \N 
1 SIMPLE  MEMBER ALL  TEAM_ID   \N  \N  \N  12  Using where 

我已经给了外键索引,但仍然mysql正在扫描成员表的所有行?为什么这样?

我使用的是5.6.12版本的mysql。

请帮忙。

回答

4

Mysql考虑进行全面扫描,而不是更好地读取索引,因为索引中的大多数值都具有值1.如果它决定扫描索引并从中获取数据,则需要进行额外的查找以获取实数来自表格的数据。这不是最佳的方式。尝试创建一个只有一个成员的第三个团队,在这种情况下,mysql必须使用索引。 Mysql将开始使用索引,因为您的数据库将会增长,与整个数据相比,更多独特的数据将存储在TEAM_ID中。这就是所谓的索引基数。请参阅此处的说明What is cardinality in MySQL?

+0

已经添加了一个团队和成员,然后试图抓取新添加的成员,然后只有一个被扫描,但对于团队1,它仍然扫描table.why的所有行? –

+0

我已经插入更多的记录到表中,它已经开始扫描匹配行而不是所有行。你有任何关于这个答案的参考? –

+0

您应该搜索索引基数。其中一个来源是https://webmonkeyuk.wordpress.com/2010/09/27/what-makes-a-good-mysql-index-part-2-cardinality/ –