2016-08-04 1 views
14

本番環境では、Railsアプリケーションで頻繁なスパイク(〜1時間ごと)が発生していました。もっと深く掘り下げていくと、1回のHTTPリクエストで累積的に1.5秒を超える(100倍と呼ばれる)次のクエリが原因です。Railsのpg_attributeテーブルの遅い暗黙のクエリを修正する方法

SELECT a.attname, format_type(a.atttypid, a.atttypmod), pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod FROM pg_attribute a 
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum 
WHERE a.attrelid = ?::regclass AND a.attnum > ? AND NOT a.attisdropped 
ORDER BY a.attnum 

は、我々は、明示的にそのテーブルを呼び出すコードを持っていますが、各モデルの属性を把握するためのRailsで呼ばれています思えるしません。 「Unexpected SQL queries to Postgres database on Rails/Heroku」は関連しています。

しかし、それはRailsによって非反復的に呼び出されるべきではありませんか?

これをどのようにスピードアップしますか?

+0

私たちがどこから電話したのか分かりましたか?もしそうなら、memcacheなどでこのレスポンスをどのようにキャッシュし、その頻度を減らすかを考え出すことができます。私はすべてのコアレールを取り除くわけではありませんが、MTLでキャッシュすると役立つかもしれません。ちょっとした考え。 – engineersmnky

+0

編集のThx。事は、明示的にこれを明示的に呼ぶことはありません。おそらく何かの副作用。どんなアイデアをどのようにバックトレースするには? –

+0

'が1.5ミリ秒を超えて実行されています。私は遅い*とは言わず、100倍と呼ばれますが、繰り返し100回は呼び出さないでしょう。これはRoRの「機能」のように見えます – joop

答えて

0

eager loadingという言葉でこれをスピードアップします。 eager_load Active Recordメソッドを使用すると、テーブルの各行に対してN + 1クエリを実行できなくなります。さもなければ、レールはあなたが何をしているのか分からず、同じテーブルにないそれぞれの属性に対して別のSELECT/JOINをデフォルトにします。

0

私はこれまでに働いたRailsアプリケーションでこの問題を経験していません。私はあなたの解決策は、あなたのプロジェクトにactive-record-query-traceを追加し、このクエリをトリガしていることを確認することだと思います。仕事で

私は、このセットアップを使用します。AR_TRACER=1 bundle exec rails s

# Gemfile 
group :test, :development do 
    gem "active-record-query-trace" 
end 

# config/initializers/ar_tracer.rb 
if ENV.has_key?("AR_TRACER") && defined? ActiveRecordQueryTrace 
    ActiveRecordQueryTrace.enabled = true 
    ActiveRecordQueryTrace.lines = 20 # you may want to increase if not enough 
end 

そして、単にあなたのレールのサーバーは次のように開始します。

関連する問題