我有1表locations
和4个相同的表:countries
,regions
,provinces
,cities
为什么不使用索引键?
所有的表的InnoDB
的所有表有一个柱id
其是主要,非空,无符号整型,汽车式增量
所有的表列name
这非空,VARCHAR,默认'
locations
持有外键的所有其他4张桌子。所有非空。
的locations
表还拥有一些其他的列和索引/键,但没有一个不相关的其他4台
现在我有这个疑问:
DESCRIBE SELECT * FROM locations
LEFT JOIN cities ON locations.city_id = cities.id
LEFT JOIN provinces ON locations.province_id = provinces.id
LEFT JOIN regions ON locations.region_id = regions.id
LEFT JOIN countries ON locations.country_id = countries.id
WHERE locations.id > 1
结果是让我满意的:所有表都使用他们的密钥。
1, SIMPLE, locations, range , PRIMARY, PRIMARY, 4, , 393, Using where
1, SIMPLE, cities , eq_ref, PRIMARY, PRIMARY, 4, mydb.locations.city_id , 1,
1, SIMPLE, provinces, eq_ref, PRIMARY, PRIMARY, 4, mydb.locations.province_id, 1,
1, SIMPLE, regions , eq_ref, PRIMARY, PRIMARY, 4, mydb.locations.region_id , 1,
1, SIMPLE, countries, eq_ref, PRIMARY, PRIMARY, 4, mydb.locations.country_id , 1,
问题:
仅改变LEFT JOIN countries
到INNER JOIN countries
是确定的。所有表格仍然使用密钥。
1, SIMPLE, locations, range , PRIMARY,locations_country_id_fk, PRIMARY, 4, , 341, Using where
1, SIMPLE, cities , eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.city_id , 1,
1, SIMPLE, provinces, eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.province_id, 1,
1, SIMPLE, regions , eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.region_id , 1,
1, SIMPLE, countries, eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.country_id , 1,
只有LEFT JOIN provinces
转变成INNER JOIN provinces
是确定的。所有表格仍然使用密钥。
1, SIMPLE, locations, range , PRIMARY,locations_province_id_fk, PRIMARY, 4, , 341, Using where
1, SIMPLE, provinces, eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.province_id, 1,
1, SIMPLE, regions , eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.region_id , 1,
1, SIMPLE, countries, eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.country_id , 1,
1, SIMPLE, cities , eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.city_id , 1,
只有LEFT JOIN cities
更改为INNER JOIN cities
是确定的。所有表格仍然使用密钥。
1, SIMPLE, locations, range , PRIMARY,locations_city_id_fk, PRIMARY, 4, , 341, Using where
1, SIMPLE, provinces, eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.province_id, 1,
1, SIMPLE, regions , eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.region_id , 1,
1, SIMPLE, countries, eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.country_id , 1,
1, SIMPLE, cities , eq_ref, PRIMARY , PRIMARY, 4, ftc_dev.locations.city_id , 1,
但只有LEFT JOIN regions
变更为INNER JOIN regions
是不确定。 regions
表不使用其密钥。我得到这个:
1, SIMPLE, regions , ALL , PRIMARY , null , null, null , 269,
1, SIMPLE, locations, ref , PRIMARY,locations_region_id_fk, locations_region_id_fk, 5, mydb.regions.id , 1, Using where
1, SIMPLE, cities , eq_ref, PRIMARY , PRIMARY , 4, mydb.locations.city_id , 1,
1, SIMPLE, provinces, eq_ref, PRIMARY , PRIMARY , 4, mydb.locations.province_id, 1,
1, SIMPLE, countries, eq_ref, PRIMARY , PRIMARY , 4, mydb.locations.country_id , 1,
这很奇怪!因为countries
,regions
,provinces
,cities
是相同的,据我可以看到!但是这种行为证明4个表格是而不是相同(朝着locations
表格)。我可能错过了什么让他们更加相同?
我已经看过SHOW TABLE STATUS LIKE 'table_name'
和DESCRIBE table_name
。几乎所有东西都是一样的。并且在有变化的地方(例如rows
,avg_row_length
,data_length
,auto_increment
, create_time
),regions
表值始终位于其他值之间的某处。
编辑:为什么我要问:
查询与留在区JOIN时间约为350毫秒(时间:10毫秒,抓取:为340mS)。
INNER JOIN查询区域大约需要550ms。 (持续时间:330ms,取指:220ms)。
EDIT2(不完全了解,但猜测这与不能够缓存办?!):
查询与地区STRAIGHT_JOIN作为LEFT JOIN执行好,并提供与INNER JOIN相同的输出。这很好。但仍然没有帮助我回答为什么regions
表的行为不同。我应该在哪里看到regions
与其他3个看似相同的表格之间的实际差异。
刚刚添加了一个编辑,指出INNER JOIN比LEFT JOIN减少 –
正如@Kickstart指出的那样,除了INNER JOIN和LEFT JOIN,我还可以做STRAIGHT_JOIN。这似乎与INNER JOIN具有相同的输出,但性能与LEFT JOIN相同。这很好。但仍然需要弄清楚,为什么“地区”表。是什么让这张桌子如此不同? –