三张桌子:人(10,000,000行),雇主(50,000行),person_achievements(250,000行)
Person (indexes ix_EmpID)
ID int (primary)
Emp_ID int
Full_Name varchar(250)
Employer (indexes ix_ID (ID) and ix_SectID (Sector_ID) and ix_Name)
ID int (primary)
Sector_ID int
Name varchar (250)
person_achievements (indexes ix_ID (ID) and ix_achievement (achievement))
ID int
Sect_ID
Achievement (varchar 250)
查询:
select p.*
from person p
join employer c
on c.ID = p.Emp_ID
join person_achievements a
on a.Sect_ID = c.Sector_ID
where a.Achievement = 'Employee of the Month'
现在我认为我创建的索引会导致此查询更好地执行。但是,它还没有。如果我删除了person_achievements表的连接并保留了where子句来选择雇主名称(也是一个索引列),那么生成25,000行只需要一秒钟。
我错过了什么?
编辑:添加了人员和雇主主键
编辑2:
"id","select_type","table","type","possible_keys","key","key_len","ref","rows","Extra"
"1","SIMPLE","a","ref","ix_SectID,ix_Achievement,ix_SectID_Achievement","ix_Achievement","253","const","12654","Using where"
"1","SIMPLE","c","ref","PRIMARY,ix_SectID","ix_SectID","8","db.a.Sect_ID","1",""
"1","SIMPLE","p","ref","Emp_ID","Emp_ID","9","db.c.ID","103","Using where"
答案 0 :(得分:1)
这是您的查询:
select p.*
from person p join
employer c
on c.ID = p.Emp_ID join
person_achievements a
on a.Sect_ID = c.Sector_ID
where a.Achievement = 'Employee of the Month';
最佳索引包括:person_achievements(Achievement, Sect_id)
,employer(sector_id, emp_id)
和person(emp_id)
。
您可以重新排列内部联接,因此您可以将查询编写为:
select p.*
from person_achievements a join
employer c
on a.Sect_ID = c.Sector_ID join
person p
on c.ID = p.Emp_ID
where a.Achievement = 'Employee of the Month';
这应该是MySQL选择用上述索引处理查询的方式。
我不明白,为什么名为person_achievements
的表格没有person_id
的列(在这种情况下为Emp_Id
)。无论是数据结构还是命名,似乎都有些不对劲。这种误解可能是问题的核心。如果该表中有人员ID,那么您的联接可能会乘以行数,因为它使用了错误的密钥。