Tech Racho エンジニアの「?」を「!」に。
  • 開発

Rails: 闇雲にインデックスを付けてはいけない(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Rails: 闇雲にインデックスを付けてはいけない(翻訳)

最近、使われてないインデックスを外す作業を行ってたのですが、やってみると出るわ出るわ。そのほとんどは、逆関連付けの不要なモデルのJOINの一部でした。次の例で考えてみましょう。

class ShoppingCart < ActiveRecord::Base
  has_many :shopping_cart_products
  has_many :products, through: :shopping_cart_products
end

class ShoppingCartProduct < ActiveRecord::Base
  belongs_to :shopping_cart
  belongs_to :product
end

class Product < ActiveRecord::Base
end

商品を含むショッピングカートとしてはごく普通の設計です。

このShoppingCartProductモデルはRailsのモデルジェネレータで作成されました。このとき、マイグレーションの他に関連付けを含むモデルクラスが作成されました。

$ bin/rails g model CartProduct quantity:integer{1} user:belongs_to product:belongs_to --no-test-framework
class CreateShoppingCartProducts < ActiveRecord::Migration
  def change
    create_table :shopping_cart_products do |t|
      t.integer :quantity, limit: 1, null: false
      t.belongs_to :shopping_cart, index: true, foreign_key: true
      t.belongs_to :product, index: true, foreign_key: true

      t.timestamps null: false
    end
  end
end

適切な処置として、このquantityカラムはnull値を許さないよう設定されていました。このとき、shopping_cart_productsに2つのインデックスがデフォルトで作成されていたことにご注目ください。

実際には、このインデックスはショッピングカートに特定の商品を含むショッピングカートを表示するうえでほとんど意味がありません。つまり、product_idごとにShoppingCartProductのクエリをかける必要などないので、このインデックスは使われていませんでした。Railsが生成するモデルやマイグレーションに、このインデックスが息を殺して潜んでいたのです。

使われてないインデックスは、データベースリソースの無駄使いです。ストレージ容量を消費し、UPDATEINSERTの速度も落ちます。このときはshopping_cart_productsがそうでした。

使われていないインデックスを取り除くのは簡単です。

class RemoveIndexShoppingCartProductsOnProductId < ActiveRecord::Migration
  def up
    remove_index(:shopping_cart_products, :product_id)
  end

  def down
    add_index(:shopping_cart_products, :product_id)
  end
end

データベースにインデックスを追加するときは、よく考えてからにしましょう。本当に必要であることを確認できてから追加すべきです。

アプリの要件は時とともに変わりますので、そのうちインデックスが必要になるかもしれません。使われてない可能性のあるインデックスを検出するために、データベースツールで定期的に監視しましょう。production環境でも最良の結果を得るためにこの点を監視しておきましょう。

関連記事

PostgreSQLデータベースで「トップN」集計をうまく扱うTopN extension(翻訳)

Rails tips: 遅いクエリのログをDB設定変更なしで取るコツ(翻訳)

pgloader 3.4.1でMySQLからPostgreSQLへスマートに移行しよう(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。