Rails의 테이블에 어떤 인덱스를 추가해야하는지


131

Rails 데이터베이스에 대한 질문이 있습니다.

  • "xxx_id"와 같은 모든 외래 키에 "index"를 추가해야합니까?
  • 자동으로 생성 된 "id"열에 "index"를 추가해야합니까?
  • 자동으로 생성 된 "id"열에 "index (unique)"를 추가해야합니까?

  • 두 개의 외래 키에 한 번 add_index (:users, [:category, :state_id])에 색인을 추가하면 어떻게됩니까? 각 키에 대한 색인을 추가하는 것과 어떻게 다른가요?

    class CreateUsers < ActiveRecord::Migration
      def self.up
        create_table :users do |t|
          t.string :name
          t.integer :category_id 
          t.integer :state_id
          t.string :email
          t.boolean :activated
          t.timestamps
        end
      # Do I need this? Is it meaningless to add the index to the primary key?
      # If so, do I need :unique => true ?
      add_index :users, :id 
      # I don't think I need ":unique => true here", right?
      add_index :users, :category_id # Should I need this?
      add_index :users, :state_id # Should I need this?
      # Are the above the same as the following?
      add_index (:users, [:category, :state_id])
      end
    end

지금까지 큰 대답. 추가 질문.

  • xxx_id에 "고유 인덱스"를 추가해야합니까?

답변:


175

"xxx_id"와 같은 모든 외래 키에 "index"를 추가해야합니까?

이 열에서 정렬시 검색 속도가 빨라지므로 더 좋습니다. 외래 키는 많이 검색됩니다.

레일 버전 5부터 인덱스가 자동으로 생성되므로 자세한 내용은 여기를 참조 하십시오 .

자동으로 생성 된 "id"열에 "index"를 추가해야합니까?

아니오, 이것은 이미 레일에 의해 이루어집니다

자동으로 생성 된 "id"열에 "index (unique)"를 추가해야합니까?

아니요, 위와 동일

두 개의 외래 키에 한 번 add_index (:users, [:category_id, :state_id])에 색인을 추가하면 어떻게됩니까? 각 키에 대한 색인을 추가하는 것과 어떻게 다른가요?

그런 다음 인덱스는 두 열의 결합 된 인덱스입니다. 하나의 category_id AND에 대한 모든 항목을 동시에 원하지 않는 한 state_id( category_id그렇지 않아야합니다) 그렇지 않으면 의미 가 없습니다 category.

이와 같은 인덱스는 다음 요청 속도를 높입니다.

# rails 2
User.find(:all, :conditions => { :state_id => some_id, :category_id => some_other_id })

# rails 3
User.where(:state_id => some_id, :category_id => some_other_id)

어디

add_index :users, :category_id
add_index :users, :state_id

이러한 요청 속도가 빨라집니다.

# rails 2+3
User.find_by_category_id(some_id)
User.find_by_state_id(some_other_id)

# or
# rails 2
User.find(:all, :conditions => {:category_id => some_id})
User.find(:all, :conditions => {:state_id => some_other_id})

# rails 3
User.where(:category_id => some_id)
User.where(:state_id => some_other_id)

xxx_id에 "고유 인덱스"를 추가해야합니까?

아니요, 이렇게하면 한 명의 사용자 만 한 범주에 속할 수 있지만 범주의 의미는 더 많은 사용자를 한 범주에 넣을 수 있다는 것 입니다. User모델 에는 이와 같은 것이 belongs_to :category있고 카테고리 모델에는과 같은 것이 has_many :users있습니다. has_many관계 가있는 경우 foreign_key필드가 고유하지 않아야합니다!

이에 대한 자세한 정보는 tadman 의 훌륭한 답변을 살펴보아야 합니다.


3
좋은 대답입니다. 추가 질문. xxx_id에 "고유 인덱스"를 추가해야합니까?
TK.

질문, 해당 필드를 명시 적으로 검색하는 경우가 거의없는 경우 외래 키를 인덱싱 하시겠습니까?
노즈

@Cyle 나는 이것이 정확하게 대답 할 수 없다. 컴퓨터, 데이터베이스의 크기 및 쿼리의 성격에 달려있다. 쿼리가 웹에서 온 경우 백그라운드 응답을 위해 빠른 응답을 얻는 것이 더 좋으며 디스크 공간을 절약 해야하는 경우 디스크 공간을 절약 해야하는 경우 항상 예라고 대답합니다. 어쨌든 색인을 추가하는 것이 문제가 아닙니다.
jigfox

111

인덱싱은 까다 롭고 미묘 할 수 있지만 적용 할 규칙을보다 쉽게 ​​결정할 수있는 일반적인 규칙이 있습니다.

가장 먼저 기억해야 할 것은 인덱스는 여러 가지 방법으로 작동 할 수 있다는 것입니다. A, B, C의 인덱스는 A, B 및 단순히 A에서도 작동하므로 인덱스를 올바르게 주문하면 인덱스를보다 다양한 용도로 사용할 수 있습니다. 전화 번호부는 성, 이름으로 색인되어 있으므로 성이나 이름과 성의 조합으로 사람들을 쉽게 찾을 수 있습니다. 그러나 이름으로 직접 조회 할 수는 없습니다. 별도의 색인이 필요합니다. 전화 번호도 마찬가지이며 색인도 작성해야합니다.

이를 염두에두고 인덱스를 작성하는 방법을 지시하는 많은 것들이 있습니다.

  • 당신이있는 경우 belongs_to- has_many관계 페어링을, 당신이 사용하는 외래 키에 인덱스가 있어야합니다.
  • 레코드를 주문했는데 페이지 매김 될 레코드가 많으면 해당 주문 열을 색인 끝에 추가해야합니다.
  • has_many :through관계 가있는 경우 조인 테이블에는 조인에 포함 된 두 속성 모두에 복합 키로 고유 한 인덱스가 있어야합니다.
  • 사용자 이름 또는 이메일과 같은 고유 식별자를 사용하여 레코드를 직접 가져 오는 경우 고유 인덱스 여야합니다.
  • has_many범위를 사용하여 관계 에서 레코드 세트를 페치 하는 경우 has_many외래 키 및 범위 열을 순서대로 포함하는 색인이 있는지 확인하십시오 .

인덱스의 목표는 데이터가 올바르게 인덱스되지 않을 때 발생하는 두려운 "테이블 스캔"또는 "파일 정렬"작업을 제거하는 것입니다.

간단히 말해, 쿼리에서보기는 응용 프로그램에 의해 생성에서 참조 열 수 있도록하고 WHERE또는 HAVING조건 ORDER BY절을 순서대로 표시됩니다.


1
모든 외래 키에 항상 Rails를 사용하려는 경우 Rails가 색인을 의미하지 않는 이유가 궁금합니다. 색인을 생성하는 것이 좋지 않은 상황이 있습니까?
여행

1
@trip index: true간단한 경우를 위해 열 정의에 추가 하는 것이 쉽지만 때로는 더 많은 제어를 원할 수도 있습니다. 외래 키에서 기본적으로 인덱스를 갖는 것은 끔찍한 기본값이 아니지만 사람들을 놀라게 할 수 있습니다.
tadman

13
  • 항상 외래 키 색인
  • 주문할 열을 항상 색인화하십시오.
  • 모든 고유 한 필드 (데이터베이스 레벨에서 고유성을 보장하기 위해 예 마이그레이션 :. add_index :users, :email, unique: true)
  • 두 가지로 주문하거나 두 가지로 검색하는 경우 (예 : order by [a, b]또는 find where( a and b )) 이중 색인이 필요합니다.

구체적인 예 :

당신이 가지고 있다면:

default_scope :order => 'photos.created_at DESC, photos.version DESC'

다음을 추가해야합니다.

add_index :photos, [:created_at, :version]

참고 : 인덱스는 디스크에서 추가 공간을 차지하므로 각 인덱스를 다시 작성해야하므로 각 레코드를 만들고 업데이트하는 속도가 느려집니다.

신용:

https://tomafro.net/2009/08/using-indexes-in-rails-choosing-additional-indexes , 레일-주문시 사용자가 생성 한 _at, 테이블에 인덱스를 추가해야합니까? 및 위의 답변.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.