我在 MySQL 中有 3 个表:
innodb_verion 1.1.8
version 5.5.29-log
Table: artist
Columns:
id int(11)
new_id varchar(50)
Table: collection
Columns:
id int(11)
new_id varchar(50)
Table: artist_collection
Columns:
artist_id int(11) PK
collection_id int(11) PK
艺术家和收藏表包含 100 行(我只是抽出一个子集来测试这个问题)
Artist_collection 表包含超过 800 万行,并有一个 PRIMARY KEY 创建为:
ALTER TABLE artist_collection ADD PRIMARY KEY (artist_id,collection_id);
当我对艺术家和收藏进行相同的连接时,收藏所花费的时间比艺术家要长得多:
SELECT artist.new_id AS 'i' FROM artist INNER JOIN artist_collection ON artist.id=artist_collection.artist_id LIMIT 100;
100 row(s) returned 0.001 sec
SELECT collection.new_id AS 'i' FROM collection INNER JOIN artist_collection ON collection.id=artist_collection.collection_id LIMIT 100;
100 row(s) returned 2.636 sec
这很重要,因为这些原始表有 1000 万多行,我不想在查询中使用 LIMIT。即使我做了 LIMIT 1000,慢速查询也需要大约 35 秒才能完成,而快速查询大约需要 0.020 秒。然后我对两个查询都做了一个 EXPLAIN EXTENDED 来看看到底发生了什么:
EXPLAIN EXTENDED SELECT artist.id AS 'i' FROM artist INNER JOIN artist_collection ON artist.id=artist_collection.artist_id LIMIT 100;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE artist ALL NULL NULL NULL NULL 82 100.00
1 SIMPLE artist_collection ref PRIMARY PRIMARY 4 tbl.artist.id 2 100.00 Using index
EXPLAIN EXTENDED SELECT collection.id AS 'i' FROM collection INNER JOIN artist_collection ON collection.id=artist_collection.collection_id LIMIT 100;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE collection ALL NULL NULL NULL NULL 101 100.00
1 SIMPLE artist_collection index NULL PRIMARY 8 NULL 8725465 100.00 Using where; Using index; Using join buffer
如您所见,它没有平等地对待查询。然后我跑了:
ALTER TABLE artist_collection DROP PRIMARY KEY;
ALTER TABLE artist_collection ADD PRIMARY KEY (collection_id,artist_id);
这导致问题自行逆转,现在艺术家 JOIN 需要很长时间。所以我的问题是这样的:
1) MySQL 是否以不同的方式解释 PRIMARY KEY 的第一个和第二个条目?
2)到底发生了什么?
3)如何使查询相等(快速)?