我有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相同。這很好。但仍然需要弄清楚,爲什麼「地區」表。是什麼讓這張桌子如此不同? –