次のように要約できるテーブル構造があります。
pagegroup
* pagegroupid
* name
3600行あります
page
* pageid
* pagegroupid
* data
ページグループを参照します。10000行あります。ページグループごとに1〜700行の範囲で指定できます。データ列のタイプはmediumtextで、列には1行あたり100k〜200kバイトのデータが含まれます
userdata
* userdataid
* pageid
* column1
* column2
* column9
参照ページ; 約300,000行あります。1ページあたり約1〜50行にすることができます
上記の構造は非常に単純です。問題は、インデックスを作成する必要のあるすべての列にインデックスを付けたにもかかわらず、userdataからページグループへの結合が非常に遅くなることです。このような結合(userdatainner_joinページinner_joinページグループ)のクエリを実行するために必要な時間は3分を超えています。データ列をまったく選択していないことを考えると、これは非常に遅いです。時間がかかりすぎるクエリの例:
SELECT userdata.column1, pagegroup.name
FROM userdata
INNER JOIN page USING( pageid )
INNER JOIN pagegroup USING( pagegroupid )
なぜそんなに時間がかかるのか、そしてそれを速くするために何ができるのかを説明するのを手伝ってください。
編集#1
次のジブリッシュのリターンを説明します。
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE userdata ALL pageid 372420
1 SIMPLE page eq_ref PRIMARY,pagegroupid PRIMARY 4 topsecret.userdata.pageid 1
1 SIMPLE pagegroup eq_ref PRIMARY PRIMARY 4 topsecret.page.pagegroupid 1
編集#2
SELECT
u.field2, p.pageid
FROM
userdata u
INNER JOIN page p ON u.pageid = p.pageid;
/*
0.07 sec execution, 6.05 sec fecth
*/
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE u ALL pageid 372420
1 SIMPLE p eq_ref PRIMARY PRIMARY 4 topsecret.u.pageid 1 Using index
SELECT
p.pageid, g.pagegroupid
FROM
page p
INNER JOIN pagegroup g ON p.pagegroupid = g.pagegroupid;
/*
9.37 sec execution, 60.0 sec fetch
*/
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE g index PRIMARY PRIMARY 4 3646 Using index
1 SIMPLE p ref pagegroupid pagegroupid 5 topsecret.g.pagegroupid 3 Using where
この話の教訓
このようなパフォーマンスの問題が発生した場合は、中/長のテキスト列を別のテーブルに保持してください。