문제

세 번째 모델 CityPermission에 합류 한 사용자와 도시의 두 가지 모델이 있다고 가정합니다.

class CityPermission < ActiveRecord::Base
  belongs_to :city
  belongs_to :user
end

class City < ActiveRecord::Base
  has_many :city_permissions
  has_many :users, :through => :city_permissions
end

class User < ActiveRecord::Base
  has_many :city_permissions
  has_many :cities, :through => :city_permissions
end

현재 다음 마이그레이션 코드 스 니펫을 사용하여 조인 테이블과 테이블 색인을 만듭니다.

create_table :city_permissions do |t|
      t.integer :user_id, :city_id
      t.other_fields ...
end

add_index(:city_permissions, :user_id)
add_index(:city_permissions, :city_id)

이것이 최적의 인덱스입니까? 이 인덱스는 조인 테이블을 통해 빠른 액세스와 테이블 자체의 빠른 조회를 통해 빠르게 액세스 할 수 있습니까? 이것을 조금 다르게 다시 만들려면이 색인이 주어집니다. city 그리고 user Class City 및 사용자의 인스턴스 변수는 허용됩니다. city.users, city.city_permissions, user.cities, 그리고 user.city_permissions 모두 똑같이 성능이 좋습니까?

도움이 되었습니까?

해결책

나 한테보기 좋다.

생성 된 조인은 엔티티 테이블의 PK ID 또는 결합 테이블의 FK ID (둘 다 인덱스 인 FK ID에 있어야합니다.

생성 된 ActiveRecord SQL을보고 인덱스와 비교하는 것이 좋을 것입니다.

어떤 데이터베이스에 있는지에 따라 설명 계획을 통해 해당 SQL을 실행할 수 있습니다 (또는 존재하는 도구는 여기에 Oracle을 생각하고 있습니다).

코드를 단순화하려면 사용을 볼 수 있습니다. has_and_belongs_to_many 또한. 그것은 당신이 CityPermission 객체를 제거 할 수있게 해줄 것입니다 (데이터 자체를 저장하는 데 사용하지 않는 한).

다른 팁

다음은 ActiveRecord가 생성하는 SQL입니다 user.cities:

SELECT `cities`.* FROM `cities` INNER JOIN city_permissions ON (cities.id = city_permissions.city_id) WHERE (city_permissions.user_id = 1 )

아래 결과 설명 :

+----+-------------+------------------+--------+---------------------------------------------------------------------+-----------------------------------+---------+-------------------------------------------------+------+-------------+
| id | select_type | table            | type   | possible_keys                                                       | key                               | key_len | ref                                             | rows | Extra       |
+----+-------------+------------------+--------+---------------------------------------------------------------------+-----------------------------------+---------+-------------------------------------------------+------+-------------+
|  1 | SIMPLE      | city_permissions | ref    | index_city_permissions_on_user_id,index_city_permissions_on_city_id | index_city_permissions_on_user_id | 5       | const                                           |    1 | Using where |
|  1 | SIMPLE      | cities           | eq_ref | PRIMARY                                                             | PRIMARY                           | 4       | barhopolis_development.city_permissions.city_id |    1 |             |
+----+-------------+------------------+--------+---------------------------------------------------------------------+-----------------------------------+---------+-------------------------------------------------+------+-------------+

그리고 여기 ActiveRecord가 생성하는 SQL이 있습니다 user.city_permissions:

SELECT * FROM `city_permissions` WHERE (`city_permissions`.user_id = 1)

해당 쿼리에 대한 설명 결과 :

+----+-------------+------------------+------+-----------------------------------+-----------------------------------+---------+-------+------+-------------+
| id | select_type | table            | type | possible_keys                     | key                               | key_len | ref   | rows | Extra       |
+----+-------------+------------------+------+-----------------------------------+-----------------------------------+---------+-------+------+-------------+
|  1 | SIMPLE      | city_permissions | ref  | index_city_permissions_on_user_id | index_city_permissions_on_user_id | 5       | const |    1 | Using where |
+----+-------------+------------------+------+-----------------------------------+-----------------------------------+---------+-------+------+-------------+

그것처럼 보인다 실제로 올바르게 작동합니다. MySQL 매뉴얼에서 :

EQ_REF

이전 테이블의 각 행 조합에 대해이 테이블에서 하나의 행을 읽습니다. 시스템 및 const 유형 이외에도 가능한 최상의 결합 유형입니다. 인덱스의 모든 부분이 조인에 의해 사용되며 인덱스는 기본 키 또는 고유 인덱스 일 때 사용됩니다.

심판

인덱스 값이 일치하는 모든 행은 이전 테이블의 각 행 조합에 대해이 테이블에서 읽습니다. 조인이 키의 가장 왼쪽 접두사 만 사용하거나 키가 기본 키 또는 고유 인덱스가 아닌 경우 Ref가 사용됩니다 (즉, 조인이 키 값을 기준으로 단일 행을 선택할 수없는 경우). 사용되는 키가 몇 줄에만 일치하는 경우 좋은 결합 유형입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top