これは私のクエリの例です:
SELECT
nickname,
CASE class_id
WHEN 1 THEN 'Druid'
WHEN 2 THEN 'Necromancer'
WHEN 3 THEN 'Mage'
WHEN 4 THEN 'Priest'
WHEN 5 THEN 'Warrior'
WHEN 6 THEN 'Stalker'
WHEN 7 THEN 'Paladin'
WHEN 8 THEN 'Psionic'
END class_name,
ROUND(AVG(level),2) level,
ROUND(AVG(tabard_id),2) tabard,
CASE rank_id
WHEN 1 THEN 'Leader'
WHEN 2 THEN 'Officer'
WHEN 3 THEN 'Veteran'
WHEN 4 THEN 'HonoryMember'
WHEN 5 THEN 'OrdinaryMember'
WHEN 6 THEN 'Alt'
WHEN 7 THEN 'Apprentice'
WHEN 8 THEN 'Penalty'
END rank_name,
ROUND(AVG(loyality),2) loyality,
ROUND((MAX(authority)-MIN(authority))/AVG(tabard_id)) authority_effective,
MAX(authority)-MIN(authority) authority_delta,
MIN(authority) authority_begin,
MAX(authority) authority_end
FROM users
LEFT JOIN level_history ON level_history.users_id = users.id
LEFT JOIN tabard_history ON tabard_history.users_id = users.id
LEFT JOIN rank_history ON rank_history.users_id = users.id
LEFT JOIN loyality_history ON loyality_history.users_id = users.id
LEFT JOIN authority_history ON authority_history.users_id = users.id
LEFT JOIN guilds_has_users ON guilds_has_users.users_id = users.id
LEFT JOIN report ON report.id = authority_history.report_id
AND report.id = level_history.report_id
AND report.id = loyality_history.report_id
AND report.id = rank_history.report_id
AND report.id = tabard_history.report_id
WHERE report.date BETWEEN '2011-10-24 00:00:00' AND '2011-10-30 23:59:59'
AND guilds_has_users.active = 1
GROUP BY users.id;
その選択の説明:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE guilds_has_users ref fk_guilds_has_users_users1,active_IDX active_IDX 1 const 139 Using where; Using temporary; Using filesort
1 SIMPLE users eq_ref PRIMARY PRIMARY 4 z92985_orlandino.guilds_has_users.users_id 1
1 SIMPLE level_history ref fk_level_history_users1,fk_level_history_report1,u... fk_level_history_users1 4 z92985_orlandino.guilds_has_users.users_id 1 Using where
1 SIMPLE report eq_ref PRIMARY,date_IDX,id_date_IDX PRIMARY 4 z92985_orlandino.level_history.report_id 1 Using where
1 SIMPLE tabard_history ref fk_tabard_history_users1,fk_tabard_history_report1... fk_tabard_history_users1 4 z92985_orlandino.level_history.users_id 1 Using where
1 SIMPLE rank_history ref fk_rank_history_users1,fk_rank_history_report1,use... fk_rank_history_users1 4 z92985_orlandino.users.id 1 Using where
1 SIMPLE loyality_history ref fk_loyality_history_users1,fk_loyality_history_rep... fk_loyality_history_users1 4 z92985_orlandino.rank_history.users_id 1 Using where
1 SIMPLE authority_history ref fk_authority_history_users1,fk_authority_history_r... fk_authority_history_users1 4 z92985_orlandino.level_history.users_id 1 Using where
その選択のプロファイリングは私に伝えます:
(139 total, Query took 4.4918 sec)
Copying to tmp table 4.488318
そしてMySQL変数に関するいくつかの情報:
SHOW VARIABLES LIKE '%buffer%';
Variable_name Value
bulk_insert_buffer_size 8388608
join_buffer_size 131072
key_buffer_size 12884901888
myisam_sort_buffer_size 8388608
net_buffer_length 16384
preload_buffer_size 32768
read_buffer_size 131072
read_rnd_buffer_size 25165824
sort_buffer_size 2097144
sql_buffer_result OFF
なぜtmpテーブルへのコピーがとても遅いのですか?クエリの速度を向上させる方法は?
PS:ホスティングプロバイダーが許可していないため、MySQLを構成できません。
セッション内で特定の変数を設定してみる必要があるかもしれません
これらの特定の値は、DB接続がクエリを効率的に実行するには小さすぎる可能性があります。これらは次のように設定できます。
SHOW VARIABLES LIKE 'max_heap_table_size';
SHOW VARIABLES LIKE 'tmp_table_size';
SET max_heap_table_size = 1024 * 1024 * 64;
SET tmp_table_size = 1024 * 1024 * 32;
一時テーブルの使用に関する MySQLドキュメントを参照してください
独自のセッション内でこれらの値を設定できない場合は、ホスティングプロバイダーに連絡して、my.cnfに動的に値を設定してください。
試してみる !!!
クエリを、出力を生成するために絶対に必要なテーブルのみに減らすことや、クエリを複数の個別のクエリに分割して、情報の異なる部分を引き出すことはできますか?
データに対して3つの個別のクエリを実行する方が、1つの巨大なクエリを実行するよりも高速であることに気付くでしょう。
自分の作品からLEFT JOIN
クエリは必ずしも最も効率的ではないため、どうしても必要な場合にのみ使用してください...
それが役に立てば幸い:)