使用多个连接优化查询

时间:2015-01-09 00:44:31

标签: mysql indexing

老实说,我真的觉得这很简单。但是,我的MySQL查询性能非常糟糕,而且我没有想法。

三张桌子:人(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"

1 个答案:

答案 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,那么您的联接可能会乘以行数,因为它使用了错误的密钥。