2017-03-02 3 views
1

私はこのテーブル作成:この複合キーがインデックスに登録されないのはなぜですか?

CREATE TABLE incident_originator (
    id_incident INT (11) UNSIGNED NOT NULL, 
    id_user INT (11) NOT NULL, 
    PRIMARY KEY (
     id_incident, 
     id_user 
    ), 
    CONSTRAINT fk_incident_incident_originator FOREIGN KEY (id_incident) REFERENCES incident_table (id_incident) ON DELETE RESTRICT ON UPDATE CASCADE, 
    CONSTRAINT fk_user_incident_originator FOREIGN KEY (id_user) REFERENCES users (id_user) ON DELETE RESTRICT ON UPDATE CASCADE 
) ENGINE = INNODB DEFAULT CHARSET = latin1; 

しかし、fk_user_incident_originatorは、インデックス化され、そしてfk_incident_incident_originatorではありません。何故ですか? InnoBDは自動的にすべての外部キーのインデックスを作成するはずですか? id_incidentのインデックスがないと、結合が遅くなるでしょうか?私が読んだほど、わかりません...

また、テーブルに値を追加すると、それらは2番目の列で順序付けされ、人間として読むには変です。

編集:私はSHOW INDEX FROM incident_originator;を行うと、それは、これを返します。

Non_unique Key_name Seq_in_index Column_name 
0 PRIMARY 1 id_incident 
0 PRIMARY 2 id_user 
1 fk_user_incident_originator 1 id_user 

答えて

1

fk_incident_incident_originatorそれは確か

ではありません。参照テーブルで

PRIMARY KEY (id_incident,id_user), 

、外部キー列が同じ順序で最初の列として表示され、インデックスが存在しなければなりません。このような索引は、参照表に存在しない場合は自動的に作成されます。

https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html

id_incident主キーの(一番左を意味する)最初の列です...と主キー制約を強制する時に値を検索するための完璧な指標です。第2のインデックスを追加することは冗長である。

同じことが結合にも当てはまります(ただし、結合は外部キーが常に索引付けされる実際の理由ではありません)。索引の左側に固定されたすべての結合列を含む索引はすべて結合に有効です。

これらは2番目の列で順序付けされており、人間として読むには変です。

人間がORDER BYを使用しない限り、データベースは人間の利益のために出力を注文していないことをご存じの人にお聞かせください。 ORDER BYのない結果セットは、定義によって順序付けされていません。行が主キー順で返されることが多いという事実は、偶然によるものであり、設計や必要性によるものではありません。この動作は、テーブルを読み込むときにオプティマイザが戦略を変えるときにテーブルが大きくなるとシフトする可能性がありますが、id_userのインデックスは実際にカバーするインデックスです(すべてのインデックスにもコピーが含まれているためより正確には、この特定のクエリを満たすために必要なすべての列が含まれています。これらは時々2つの異なるものです。これは実際のコードでSELECT *を使用しない最もよい理由の1つです)オプティマイザはソースとしてそのオプティマイザを選択しています。選択したインデックスからインデックス順の行が読み込まれ、その順序は結果の完全な偶然順序になります。

+0

'show index 'の結果を質問に追加しました。あなたが言うように、' fk_incident_incident_originator'が索引付けされていないからです。それは 'SHOW INDEX'の結果に表示されるべきではありませんか? について >選択したインデックスからインデックス順に行が読み込まれ、その順序が完全に偶然の結果の順序になります。 PRIMARYキーおよびSeq_in_index値のインデックス順は、最初にid_incidentで列を順序付けする必要があることを示していますか? とにかく、私は 'SELECT *'を使用しないでも、クエリの結果を順序付けしなくても、注文のことはもっと好奇心です。 – Tyrannogina

+0

なぜ 'SHOW INDEX'が混乱しているのかは、' fk_user_incident_originator'があなたが何を意味するのかを意味しないからです。これはインデックス名であり、偶然には制約記号と同じです。最初にuser_idにインデックスを追加した後、この外部キーを追加した場合、それは 'SHOW INDEX'にも表示されません。 –

関連する問題