あなたの柵データベース質問について説明する5つの方法


EXPLAIN 自分自身
走るEXPLAIN 異なるデータベースクエリの実行計画を表示するには、特定のデータベース相互作用のパフォーマンスがなぜ方法であるかを理解し、どのように改善できるかを理解できます.この計画の目的は、実行計画の結果を解釈し理解することではない.むしろ、我々はあなたの柵アプリからこの情報を得ることができる5つの異なる方法を学びます.
これらの例のいくつかはPostgreSQL固有です.

1 . ActiveRecordのexplain 方法
レールには既にexplain 方法built into ActiveRecord使用するために.を追加することができますexplain 任意のActiveRecordの関係に、あなたは
施工計画.
> User.where(email: "[email protected]").explain
=> EXPLAIN for: SELECT "users".* FROM "users" WHERE "users"."email" = $1 [["email", "[email protected]"]]
                      QUERY PLAN
-------------------------------------------------------
 Seq Scan on users  (cost=0.00..2.71 rows=1 width=340)
   Filter: ((email)::text = '[email protected]'::text)
(2 rows)
これは私たちに大きな出発点を与え、様々なデータベース間で動作します.ただし、いくつかの追加機能が必要な場合などrunning EXPLAIN ANALYZE , 他の場所を見る必要があるでしょう.

2 . ActiveRecord接続内のクエリの補間
あなた自身のSQLステートメントを作成し、それをActiveRecordのexecute メソッド.しかし、おそらく、ActiveRecordの構文を使用して書いたSQLクエリを書く際に、エラーを起こしがちで労苦する努力をしたくないでしょう.
幸いにも、あなたがする必要はありません!ActiveRecordクエリを文字列に変換できます.to_sql , を追加し、execute :
> ActiveRecord::Base.connection.execute("EXPLAIN #{User.where(email: "[email protected]").to_sql}").values
=> [["Seq Scan on users  (cost=0.00..2.71 rows=1 width=340)"], ["  Filter: ((email)::text = '[email protected]'::text)"]]
これはActiveRecordのものを使用してすべての勝利の多くではないexplain メソッド.それは長いです、あなたはつかむために覚えているvalues からexecute 結果、出力はうまくフォーマットされません.しかし、これはあなたが実行しているexecute , 任意の機能を使用することができます選択のデータベースエンジンのようなものを提供するEXPLAIN ANALYZE :
> ActiveRecord::Base.connection.execute("EXPLAIN ANALYZE #{User.where(email: "[email protected]").to_sql}").values
=> [["Seq Scan on users  (cost=0.00..2.71 rows=1 width=340) (actual time=0.184..0.233 rows=0 loops=1)"],
 ["  Filter: ((email)::text = '[email protected]'::text)"],
 ["  Rows Removed by Filter: 57"],
 ["Planning time: 0.185 ms"],
 ["Execution time: 0.472 ms"]]
ありがとうMark Lodato この推薦のために.

3 . Analerecordの解析
いくつかの説明的なパワーを得るために依存関係を考慮したいなら、ActiveRecord 4から6を使用し、PostgreSQLを使用してくださいactiverecord-explain-analyze ジェム.
ここであなたの出力書式を指定できますEXPLAIN 結果、および呼び出しEXPLAIN ANALYZE :
> User.where(email: "[email protected]").explain(analyze: true)
=> EXPLAIN for: SELECT "users".* FROM "users" WHERE "users"."email" = $1
Seq Scan on public.users  (cost=0.00..2.71 rows=1 width=340) (actual time=0.120..0.128 rows=0 loops=1)
  Output: id, email, sign_in_count, current_sign_in_at, last_sign_in_at, current_sign_in_ip, last_sign_in_ip, created_at, updated_at, time_zone, first_name, last_name, role, applicant_id, centrify_uuid, display_name, uuid, login_authorized, invite_id, legacy_identifier, disabled_at, invite_sent_at, password_last_changed_at, deprovisioning_reason
  Filter: ((users.email)::text = '[email protected]'::text)
  Rows Removed by Filter: 57
  Buffers: shared hit=2
Planning time: 0.277 ms
Execution time: 0.183 ms

PG眼球玉
pg-eyeballs はPostgreSQL特有の別の宝石であり、ActiveRecordのexplain メソッドは現在は使用しません.
我々の求めた後EXPLAIN ANALYZE あなたが要求できる多くのオプションの一つです.
> User.where(email: "[email protected]").eyeballs.explain(options: [:analyze])
=> ["Seq Scan on users  (cost=0.00..2.71 rows=1 width=340) (actual time=0.028..0.036 rows=0 loops=1)\n  Filter: ((email)::text = '[email protected]'::text)\n  Rows Removed by Filter: 57\nPlanning time: 0.087 ms\nExecution time: 0.084 ms"]

データベースのターミナルCLI
これらの前の例の全てはRailsコンソールのような柵プロセスの範囲内で実行されました.しかし、我々は完全にレールをスキップし、直接データベースを使用することができます.PostgreSQLの場合、我々は使用できますpsql .
# psql -U postgres
接続後、どのデータベースが存在するかを一覧表示できます\l .
postgres=# \l
                                              List of databases
                Name                 |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-------------------------------------+----------+----------+------------+------------+-----------------------
 example_app_development             | postgres | UTF8     | en_US.utf8 | en_US.utf8 |

正しいデータベースを見つけた後、我々はそれに接続することができます\c .
postgres=# \c example_app_development
として説明します.
example_app_development=# EXPLAIN SELECT * FROM USERS WHERE EMAIL = '[email protected]';
                      QUERY PLAN
------------------------------------------------------------
 Seq Scan on users  (cost=0.00..2.71 rows=1 width=340)
   Filter: ((email)::text = '[email protected]'::text)
(2 rows)
再び、我々はすべての機能を我々のデータベースエンジンをサポートしているので、我々は使用できるようにしているEXPLAIN ANALYZE または他の機能は、それを必要とせずにレールに組み込まれる.これは私たちのデータベースを提供するすべてのパワーを与えますが、我々はActiveRecordのクエリAPIの表現性を失う-または
むしろ、我々は.to_sql これを使用する前に興味のあるクエリの表現.
EXPLAIN 使用するing
既存のActiveRecordクエリの実行計画をすばやく取得する場合は、ActiveRecordのexplain メソッド.
あなたのデータベースエンジンが提供するより多くの機能を必要とするならば、あなたはそうすることができますexecute 任意のクエリをActiveRecordを介してデータベースにしたいと思います.
あなたがそのような追加機能を必要とするならばEXPLAIN ANALYZE , 定期的に、あなたのためにそれを提供する追加の依存関係を考慮することactiverecord-explain-analyze or pg-eyeballs .
あなたがデータベースとしてレールを使用せずに直接あなたのデータベースに行くことを忘れないでください.
これが欲しいEXPLAIN あなたの質問のためにパフォーマンス情報を集める方法について、ものか2か(または5).したら、どの方法はあなたのために、幸運を最適化を決定!

This post originally published on The Gnar Company blog.