web-dev-qa-db-ja.com

クエリ、テーブルは同じですが、EXPLAINとパフォーマンスが異なります

2つのテーブルlevelsusers_favoritesがあります

 + -------------------- + -------------- + ------ +- ---- + --------- + ------- + 
 |フィールド|タイプ|ヌル|キー|デフォルト|追加| 
 + -------------------- + -------------- + ------ + ----- + --------- + ------- + 
 | id | int(9)|いいえ| PRI | NULL | | 
 | user_id | int(10)| NO | MUL | NULL | | 
 | level_name | varchar(20)| NO | | NULL | | 
 | user_name | varchar(45)| NO | | NULL | | 
 |評価| decimal(3,2)| NO | | 2.50 | | 
 |投票| int(5)| NO | | 0 | | 
 |再生| int(5)| NO | | 0 | | 
 | date_published |日付| NO | MUL | NULL | | 
 | user_comment | varchar(255)| YES | | NULL | | 
 | playable_character | int(2)| NO | MUL | 1 | | 
 | is_featured | tinyint(1)|いいえ| MUL | 0 | | 
 + -------------------- + -------------- +- ----- + ----- + --------- + ------- + 
 + ---------- + -------- + ------ + ----- + --------- +- ------ + 
 |フィールド|タイプ|ヌル|キー|デフォルト|追加| 
 + ---------- + -------- + ------ + ----- + --------- + ------- + 
 | user_id | int(8)|いいえ| PRI | NULL | | 
 | level_id | int(8)| NO | PRI | NULL | | 
 +- --------- + -------- + ------ + ----- + --------- + ------- + 

ローカル開発環境と運用サーバーがあります。このクエリ:

 SELECT id、level_name、date_published、rating 
 FROMレベル
 WHERE id IN(SELECT level_id FROM users_favorites WHERE user_id = 2); 

ローカルで非常に高速に実行され(約0.0x秒)、本番環境では非常に低速です(〜15秒)。 EXPLAINは異なります。ローカル:

 id select_type table type potential_keys key key_len ref rows Extra 
 1 SIMPLE users_favorites ref uniq_user_level、idx_user idx_user 4 const 21 "Using index" 
 1 SIMPLE levels eq_ref PRIMARY PRIMARY 4 users_favorites.level_id 1「場所の使用」

そして生産について:

 id select_type table type potential_keys key key_len ref rows Extra 
 1 PRIMARY levels ALL NULL NULL NULL NULL 3368988 "Using where" 
 2 "DEPENDENT SUBQUERY" users_favorites eq_ref uniq_user_level、idx_user uniq_user_level 8 const、func 1 "インデックスの使用" 

同じスキーマからインポートおよびエクスポートされたため、データは同じです。 OPTIMIZEを実行して、インデックスが同じであることを確認し、インデックスを強制的に実行しました。何もうまくいきませんでした。

私が見つけることができる唯一の違いは、MySQLのバージョンです。ローカルでは5.6.10、本番環境では5.5.34ログです。それが理由ならアップグレードしますが、他に理由があるのではないかと思っています。または、ローカルで行うように、常に最初にサブクエリによって減少するようにクエリをフレーズする方法:3368988ではなく21行?

TIA

5
Hal50000

単純な結合を行うだけです。サブクエリは非常に頻繁に最良の結果を提供しません

EXPLAIN SELECT l.id, l.level_name, l.date_published, l.rating
FROM levels AS l
INNER JOIN users_favorites AS uf 
ON uf.level_id = l.id
WHERE l.user_id = 2;
3
georgecj11