2016-08-30 4 views
0

1対多の関係を持つ2つの表を作成しました。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 &チーム2は、4つの部材を有する、8員を有しています。

今すぐ私はチーム&メンバーの詳細を取得するために、次の結合クエリを実行しています。

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

インデックスの値の大部分が値1を持つため、Mysqlはインデックスをより良く読み取るのではなく、完全スキャンとみなします。インデックスをスキャンしてデータをフェッチすることにした場合、テーブルからのデータ。それは最適な方法ではありません。 1つのメンバだけで3番目のチームを作成してみてください。この場合、mysqlはindexを使用する必要があります。データベース全体のデータと比較して、TEAM_IDに固有のデータが格納されるため、MySQLがインデックスを使用し始めます。インデックス基数と呼ばれます。ここでの説明を参照してくださいWhat is cardinality in MySQL?

+0

追加されたメンバーを1人追加して新しく追加されたメンバーを取得しようとすると、1人だけがスキャンされますが、チーム1の場合はまだテーブルのすべての行をスキャンしています。 –

+0

テーブルにレコードを追加しましたが、すべての行ではなく一致する行のスキャンが開始されました。この回答に関する参考資料はありますか? –

+0

インデックスのカーディナリティを検索する必要があります。ソースの1つはhttps://webmonkeyuk.wordpress.com/2010/09/27/what-makes-a-good-mysql-index-part-2-cardinality/ –

関連する問題