前に下記の記事で紹介したActiveRecord::Relation#explain
でJSON形式を取得出来るモンキーパッチを紹介したのですが、
今回はそれをGemとして公開したのでそれについて書きます💎✨
Gemはactive_record_json_explain
としてRubyGems.orgに公開してます!
公開したGemのurlは下記です🙌
コードはこちらです🐙
導入方法
導入方法は簡単で下記のようにGemfileに追加して、
gem 'active_record_json_explain', require: false
有効化したい箇所でrequire
してください🙋
require 'active_record_json_explain'
require後からgemで定義しているモンキーパッチが有効になります🐵
※既存のexplainには影響しない実装にしています。
使い方
出来ることは前回のブログにも記載していますが、ActiveRecord::Relation#explain
の引数にjson: true
を渡すをJSON形式でEXPLAINの結果を取得出来ます👍
以下が実際にMySQLを使っている場合の結果になります🐬
$ require 'active_record_json_explain' # モンキーパッチの有効化 => true $ Sample.with_title.explain(json: true) => EXPLAIN for: SELECT `samples`.* FROM `samples` WHERE `samples`.`title` = 'hoge' +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | EXPLAIN | +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | { "query_block": { "select_id": 1, "cost_info": { "query_cost": "0.35" }, "table": { "table_name": "samples", "access_type": "ALL", "rows_examined_per_scan": 1, "rows_produced_per_join": 1, "filtered": "100.00", "cost_info": { "read_cost": "0.25", "eval_cost": "0.10", "prefix_cost": "0.35", "data_read_per_join": "1K" }, "used_columns": [ "id", "category", "title", "body" ], "attached_condition": "(`sample`.`samples`.`title` = 'hoge')" } } } | +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
PostgreSQLにも対応していて下記のような形で取得出来ます 🐘
$ require 'active_record_json_explain' # モンキーパッチの有効化 => true Sample.with_title.explain(json: true) => EXPLAIN for: SELECT "samples".* FROM "samples" WHERE "samples"."title" = $1 [["title", "hoge"]] QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ [ { "Plan": { "Node Type": "Seq Scan", "Parallel Aware": false, "Relation Name": "samples", "Alias": "samples", "Startup Cost": 0.00, "Total Cost": 11.62, "Plan Rows": 1, "Plan Width": 556, "Filter": "((title)::text = 'hoge'::text)" } } ] (1 row)
おわりに
前回の記事で書いた通りJSON形式のEXPLAINは特にMySQLだとオプティマイザが判断したクエリのコストが表示されリファクタリング時に有用な情報を取得出来るので便利かなと思います👍
クエリチューニングを行うとき等に使っていただければ🙌