双内连接太慢
Double Inner Join Too Slow
嘿,我环顾四周,找不到解决我问题的方法。
我有一个包含 3 个表的营养数据库。所有 3 个表格都有单个项目的名称、营养成分和测量单位。我想要 return 单一营养素含量最高的物品,即。蛋白质。
我当前的查询需要大约 3 秒才能获得条目,这将是一个问题,因为我将在一个页面中针对多种营养素多次进行此查询。感谢任何帮助。
food_des - about 8,000 entries
+-------+---------+--------+
|NDB_No |Long_Desc|Fd_Group|
+-------+---------+--------+
|01001 |Banana |0100 |
|01002 |Apple |0102 |
+-------+---------+--------+
nut_data - about 600,000 entries
+-------+-------+--------+
|NDB_No |Nutr_No|Nutr_Val|
+-------+-------+--------+
|01001 |318 |55.5 |
|01001 |320 |1.1 |
|01002 |318 |30.2 |
|01002 |325 |12.3 |
+-------+-------+--------+
nut_def - about 150 entries
+-------+--------+-----+
|Nutr_No|NutrDesc|Units|
+-------+--------+-----+
|318 |Carbs |g |
|319 |Energy |kcal |
|320 |Protein |g |
|325 |Iron |mg |
+-------+--------+-----+
SELECT food_des.Long_Desc, nut_data.Nutr_Val, nutr_def.Units
FROM food_des
INNER JOIN nut_data
ON food_des.NDB_No=nut_data.NDB_No
INNER JOIN nutr_def
ON nut_data.Nutr_No=nutr_def.Nutr_No
WHERE nutr_def.NutrDesc="Vitamin D"
ORDER BY Nutr_Val DESC
LIMIT 5
WHERE nutr_def.NutrDesc="Vitamin D"
求 INDEX(NutrDesc)
。因此,假设优化器从 nutr_def 开始,那么它将需要移动到 nut_data,这将需要 INDEX(Nutr_No)
,然后是 food_des,需要 INDEX(NDB_No)
.
如果优化器选择从 ORDER BY 开始,那么 INDEX(Nutr_Val)
将是有益的。 (使用 JOIN 时请限定字段!我们无法分辨是哪个 table !)因此,如果它以 table 开头,请按照 JOIN 来查看其他两个需要哪些索引tables.
如果需要进一步讨论,请提供SHOW CREATE TABLE
和EXPLAIN SELECT...
。
运行这个
EXPLAIN SELECT food_des.Long_Desc, nut_data.Nutr_Val, nutr_def.Units
FROM food_des INNER JOIN nut_data
ON food_des.NDB_No=nut_data.NDB_No
INNER JOIN nutr_def
ON nut_data.Nutr_No=nutr_def.Nutr_No
WHERE nutr_def.NutrDesc="Vitamin D"
ORDER BY Nutr_Val DESC
LIMIT 5
然后决定要添加索引的位置
嘿,我环顾四周,找不到解决我问题的方法。 我有一个包含 3 个表的营养数据库。所有 3 个表格都有单个项目的名称、营养成分和测量单位。我想要 return 单一营养素含量最高的物品,即。蛋白质。
我当前的查询需要大约 3 秒才能获得条目,这将是一个问题,因为我将在一个页面中针对多种营养素多次进行此查询。感谢任何帮助。
food_des - about 8,000 entries
+-------+---------+--------+
|NDB_No |Long_Desc|Fd_Group|
+-------+---------+--------+
|01001 |Banana |0100 |
|01002 |Apple |0102 |
+-------+---------+--------+
nut_data - about 600,000 entries
+-------+-------+--------+
|NDB_No |Nutr_No|Nutr_Val|
+-------+-------+--------+
|01001 |318 |55.5 |
|01001 |320 |1.1 |
|01002 |318 |30.2 |
|01002 |325 |12.3 |
+-------+-------+--------+
nut_def - about 150 entries
+-------+--------+-----+
|Nutr_No|NutrDesc|Units|
+-------+--------+-----+
|318 |Carbs |g |
|319 |Energy |kcal |
|320 |Protein |g |
|325 |Iron |mg |
+-------+--------+-----+
SELECT food_des.Long_Desc, nut_data.Nutr_Val, nutr_def.Units
FROM food_des
INNER JOIN nut_data
ON food_des.NDB_No=nut_data.NDB_No
INNER JOIN nutr_def
ON nut_data.Nutr_No=nutr_def.Nutr_No
WHERE nutr_def.NutrDesc="Vitamin D"
ORDER BY Nutr_Val DESC
LIMIT 5
WHERE nutr_def.NutrDesc="Vitamin D"
求 INDEX(NutrDesc)
。因此,假设优化器从 nutr_def 开始,那么它将需要移动到 nut_data,这将需要 INDEX(Nutr_No)
,然后是 food_des,需要 INDEX(NDB_No)
.
如果优化器选择从 ORDER BY 开始,那么 INDEX(Nutr_Val)
将是有益的。 (使用 JOIN 时请限定字段!我们无法分辨是哪个 table !)因此,如果它以 table 开头,请按照 JOIN 来查看其他两个需要哪些索引tables.
如果需要进一步讨论,请提供SHOW CREATE TABLE
和EXPLAIN SELECT...
。
运行这个
EXPLAIN SELECT food_des.Long_Desc, nut_data.Nutr_Val, nutr_def.Units
FROM food_des INNER JOIN nut_data
ON food_des.NDB_No=nut_data.NDB_No
INNER JOIN nutr_def
ON nut_data.Nutr_No=nutr_def.Nutr_No
WHERE nutr_def.NutrDesc="Vitamin D"
ORDER BY Nutr_Val DESC
LIMIT 5
然后决定要添加索引的位置