Using filesort
必ずしも悪いことではありません。名前は少し誤解を招くです。 「ファイル」が含まれていますが、データがハードディスクのどこかに書き込まれているという意味ではありません。まだメモリ内で処理されています。
マニュアル から :
クエリでこれが発生する理由を理解していますか?この種のサブクエリを使用することは、依存であるため、悪いスタイルです。 サブクエリ。 app
のすべての行 サブクエリが実行されるテーブル。ひどい。 join
を使用してクエリを書き直します 。
select app.id,
gp.dateup
from app
join gamesplatform_pricehistory gp on gp.id_app = app.id
where app.id > 0
and gp.country = 1
and gp.dateup = (SELECT MAX(dateup) FROM gamesplatform_pricehistory smgp WHERE smgp.id_app = gp.id_app AND smgp.country = 1)
;
これは引き続き依存サブクエリを使用しますが、explain
はるかに良く見えます:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|----|--------------------|-------|-------|---------------|---------|---------|----------------------------|------|--------------------------|
| 1 | PRIMARY | app | index | PRIMARY | PRIMARY | 4 | (null) | 2 | Using where; Using index |
| 1 | PRIMARY | gp | ref | id_app | id_app | 5 | db_2_034bc.app.id,const | 1 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | smgp | ref | id_app | id_app | 5 | db_2_034bc.gp.id_app,const | 1 | Using index |
それを書き直す別の方法は、これです:
select app.id,
gp.dateup
from app
LEFT join
(SELECT id_app, MAX(dateup) AS dateup
FROM gamesplatform_pricehistory
WHERE country = 1
GROUP BY id_app
)gp on gp.id_app = app.id
where app.id > 0
;
説明はさらに良く見えます:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|----|-------------|----------------------------|-------|---------------|---------|---------|--------|------|--------------------------|
| 1 | PRIMARY | app | index | PRIMARY | PRIMARY | 4 | (null) | 2 | Using where; Using index |
| 1 | PRIMARY | <derived2> | ALL | (null) | (null) | (null) | (null) | 2 | |
| 2 | DERIVED | gamesplatform_pricehistory | index | (null) | id_app | 13 | (null) | 2 | Using where; Using index |
そして、これが依存サブクエリをまったく持たないバージョンです:
select app.id,
gp.dateup
from app
left join gamesplatform_pricehistory gp on gp.id_app = app.id and country = 1
left join gamesplatform_pricehistory gp2 on gp.id_app = app.id and country = 1 and gp.dateup < gp2.dateup
where app.id > 0
and gp2.dateup is null
;
これは次のように機能します:gp.dateup
の場合 最大で、gp2.dateup
はありません 。