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)
そのクエリの EXPLAIN の結果:
+----+-------------+------------------+------+-----------------------------------+-----------------------------------+---------+-------+------+-------------+
| 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
前のテーブルの行の組み合わせごとに、このテーブルから 1 行が読み取られます。system 型と const 型以外では、これが最適な結合型です。これは、インデックスのすべての部分が結合によって使用され、インデックスが PRIMARY KEY または UNIQUE インデックスである場合に使用されます。
参照
前のテーブルの行の組み合わせごとに、一致するインデックス値を持つすべての行がこのテーブルから読み取られます。結合がキーの左端のプレフィックスのみを使用する場合、またはキーが PRIMARY KEY または UNIQUE インデックスでない場合 (つまり、結合がキー値に基づいて単一の行を選択できない場合)、ref が使用されます。使用されるキーが数行しか一致しない場合、これは適切な結合タイプです。