我在使用 MySQL (innoDB) 5.0 时遇到了严重问题。
一个非常简单的 SQL 查询执行一个非常意外的查询计划。
查询:
SELECT
SQL_NO_CACHE
mbCategory.*
FROM
MBCategory mbCategory
INNER JOIN ResourcePermission as rp
ON rp.primKey = mbCategory.categoryId
where mbCategory.groupId = 12345 AND mbCategory.parentCategoryId = 0
limit 20;
MBCategory - 包含 216583 行
ResourcePermission - 包含 3098354 行。
在 MBCategory 中,我有多个索引(列顺序与索引相同):
Primary (categoryId)
A (groupId,parentCategoryId,categoryId)
B (groupId,parentCategoryId)
在 ResourcePermission 我有多个索引(列顺序与索引相同):
Primary - on some column
A (primKey).
当我查看查询计划时,Mysql 首先更改表序列并从 ResourcePermission 中选择行,然后加入 MBCategory 表(疯狂的想法),这需要很长时间。所以我添加STRAIGHT_JOIN
了强制innodb引擎使用正确的表序列:
SELECT
STRAIGHT_JOIN SQL_NO_CACHE
mbCategory.*
FROM
MBCategory
mbCategory
INNER JOIN ResourcePermission as rp
ON rp.primKey = mbCategory.categoryId
where mbCategory.groupId = 12345 AND mbCategory.parentCategoryId = 0
limit 20;
但是这里的第二个问题materialzie:在我看来,mysql应该index A (primKey)
在连接操作上使用,而不是它对每条记录执行范围检查(索引映射:0x400),这又需要很长时间!强制索引没有帮助,mysql 仍在为每条记录执行 Range 检查。
MBCategory 中只有 23 行满足 where 条件,加入后只有 75 行。如何让 mysql 在此操作中选择正确的索引?