28. 負荷の少ないクエリとは?
EXPLAIN
mysql> EXPLAIN SELECT `answers`.`id` AS t0_r0, `answers`.`old_id` AS t0_r1, `answers`.`question_id` AS t0_r2,
`answers`.`user_id` AS t0_r3, `answers`.`question_user_id` AS t0_r4, `answers`.`to_user_id` AS t0_r5,
`answers`.`parent_id` AS t0_r6, `answers`.`content` AS t0_r7, `answers`.`ng_word` AS t0_r8, `answers`.`check` AS
t0_r9, `answers`.`active` AS t0_r10, `answers`.`created_at` AS t0_r11, `answers`.`updated_at` AS t0_r12,
`questions`.`id` AS t1_r0, `questions`.`old_id` AS t1_r1, `questions`.`old_random_key` AS t1_r2,
`questions`.`parent_category_id` AS t1_r3, `questions`.`category_id` AS t1_r4, `questions`.`user_id` AS t1_r5,
`questions`.`to_user_id` AS t1_r6, `questions`.`type_id` AS t1_r7, `questions`.`is_serious` AS t1_r8,
`questions`.`content` AS t1_r9, `questions`.`ng_word` AS t1_r10, `questions`.`display` AS t1_r11, `questions`.`check`
AS t1_r12, `questions`.`access_count` AS t1_r13, `questions`.`use_image` AS t1_r14, `questions`.`image_url` AS
t1_r15, `questions`.`link_url` AS t1_r16, `questions`.`active` AS t1_r17, `questions`.`answer_last_updated_at` AS
t1_r18, `questions`.`created_at` AS t1_r19, `questions`.`updated_at` AS t1_r20, `questions`.`last_answer_id` AS t1_r21
FROM `answers` INNER JOIN `users` ON `users`.`id` = `answers`.`user_id` INNER JOIN `questions` ON
`questions`.`id` = `answers`.`question_id` WHERE `answers`.`active` = 1 AND (answers.user_id = 1) AND
(answers.question_user_id != 1) AND (answers.to_user_id = 1 OR answers.to_user_id is NULL) AND
(questions.active = 1) AND (questions.id IN ( SELECT temp_a.question_id FROM answers as temp_a WHERE
temp_a.user_id = 1 )) AND (answers.ng_word IN (0, 1)) GROUP BY answers.question_id ORDER BY
questions.answer_last_updated_at desc;
29. 負荷の少ないクエリとは?
EXPLAIN
+----+--------------------+-----------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------+---------+------------------------------------+------+----------------------------------------------+
| id | select_type
| table | type
| possible_keys
| key
| key_len | ref
| rows | Extra
|
+----+--------------------+-----------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------+---------+------------------------------------+------+----------------------------------------------+
| 1 | PRIMARY
| users | const
| PRIMARY
| PRIMARY
|4
| const
| 1 | Using index; Using temporary; Using filesort |
| 1 | PRIMARY
| answers | ref
|
index_answers_on_question_id_and_user_id_and_created_at,index_answers_on_question_id_and_created_at,index_answers_on_user_id_and_created_at,index_answers_on_
to_user_id_and_created_at,index_answers_on_question_user_id_and_created_at | index_answers_on_user_id_and_created_at
|4
| const
| 196
| Using where
|
| 1 | PRIMARY
| questions | eq_ref
| PRIMARY,index_questions_on_id
| PRIMARY
|4
| rio_production.answers.question_id | 1 | Using where
|
| 2 | DEPENDENT SUBQUERY | temp_a | index_subquery |
index_answers_on_question_id_and_user_id_and_created_at,index_answers_on_question_id_and_created_at,index_answers_on_user_id_and_created_at
| index_answers_on_question_id_and_user_id_and_created_at | 8
| func,const
| 4 | Using index; Using where
|
+----+--------------------+-----------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------+---------+------------------------------------+------+----------------------------------------------+
4 rows in set (0.01 sec)
104. Railsでのチューニング
ActiveRecordが生成するSQLを知る
mysqldumpslow
$ mysqldumpslow -t 5 -s t mysql-slow.log*
Reading mysql slow query log from mysql-slow.log
Count: 14591 Time=1.57s (22851s) Lock=0.00s (5s) Rows=10.0 (145910),
rio_slave[rio_slave]@8hosts
SELECT `questions`.* FROM `questions` WHERE `questions`.`display` = 'S'
AND `questions`.`to_user_id` IS NULL AND `questions`.`active` = N AND
(answer_last_updated_at != created_at) AND (questions.created_at >= 'S') AND
(ng_word IN (N, N)) ORDER BY answer_last_updated_at desc LIMIT N
OFFSET N
…
108. Railsでのチューニング
Eager Loadingを利用する
Question.limit(10).each do |q|
p “#{q.user} posted #{q.content}”
end
Question Load (9.8ms) SELECT `questions`.* FROM `questions`
User Load (5.2ms) SELECT `users`.* FROM `users` WHERE
User Load (4.1ms) SELECT `users`.* FROM `users` WHERE
User Load (4.8ms) SELECT `users`.* FROM `users` WHERE
User Load (7.9ms) SELECT `users`.* FROM `users` WHERE
User Load (5.7ms) SELECT `users`.* FROM `users` WHERE
User Load (5.4ms) SELECT `users`.* FROM `users` WHERE
User Load (4.5ms) SELECT `users`.* FROM `users` WHERE
User Load (4.4ms) SELECT `users`.* FROM `users` WHERE
User Load (4.2ms) SELECT `users`.* FROM `users` WHERE
User Load (4.4ms) SELECT `users`.* FROM `users` WHERE
109. Railsでのチューニング
Eager Loadingを利用する
Question.includes(:user).limit(10).each do |q|
p “#{q.user} posted #{q.content}”
end
Question Load (9.8ms) SELECT `questions`.* FROM `questions`
User Load (5.2ms) SELECT `users`.* FROM `users` WHERE
User Load (4.1ms) SELECT `users`.* FROM `users` WHERE
User Load (4.8ms) SELECT `users`.* FROM `users` WHERE
User Load (7.9ms) SELECT `users`.* FROM `users` WHERE
User Load (5.7ms) SELECT `users`.* FROM `users` WHERE
User Load (5.4ms) SELECT `users`.* FROM `users` WHERE
User Load (4.5ms) SELECT `users`.* FROM `users` WHERE
User Load (4.4ms) SELECT `users`.* FROM `users` WHERE
User Load (4.2ms) SELECT `users`.* FROM `users` WHERE
User Load (4.4ms) SELECT `users`.* FROM `users` WHERE
110. Railsでのチューニング
Eager Loadingを利用する
Question.includes(:user).limit(10).each do |q|
p “#{q.user} posted #{q.content}”
end
Question Load (6.9ms) SELECT `questions`.* FROM `questions`
User Load (5.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IN (724,
1402, 2277, 3154, 3696, 4180, 4551, 5375, 6090, 6890)
111. Railsでのチューニング
Eager Loadingを利用する
Question.includes(:user).limit(10).each do |q|
p “#{q.user} posted #{q.content}”
end
Question Load (6.9ms) SELECT `questions`.* FROM `questions`
User Load (5.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IN (724,
1402, 2277, 3154, 3696, 4180, 4551, 5375, 6090, 6890)
117. Railsでのチューニング
インスタンス変数によるキャッシュ
1接続内に複数回SQLが発行される場合
Question.first.tap do |q|
10.times { "answers count is #{q.answers.count}" }
end
Question Load (8.0ms) SELECT `questions`.* FROM `questions`
(4.2ms) SELECT COUNT(*) FROM `answers` WHERE
(3.6ms) SELECT COUNT(*) FROM `answers` WHERE
(5.3ms) SELECT COUNT(*) FROM `answers` WHERE
(3.8ms) SELECT COUNT(*) FROM `answers` WHERE
(3.8ms) SELECT COUNT(*) FROM `answers` WHERE
(5.7ms) SELECT COUNT(*) FROM `answers` WHERE
(3.8ms) SELECT COUNT(*) FROM `answers` WHERE
(3.4ms) SELECT COUNT(*) FROM `answers` WHERE
(3.8ms) SELECT COUNT(*) FROM `answers` WHERE
(5.4ms) SELECT COUNT(*) FROM `answers` WHERE