通过多重连接提高最大 n 的性能

Improve performance on greatest n with multiple join

所以我正在播放一些 sql 索引,看看是否可以提高我的 sql 性能。我正在使用来自员工 table https://github.com/datacharmer/test_db 的数据,并转储 employees.sql.

稍微查看一下结构后,我的问题是如何找到薪水最高的 10 个人以及头衔是什么。我想出了一些解决方案。

select e.emp_no, e.first_name, e.last_name, e.gender, salaries.salary, titles.title from employees e
inner join ( 
    select s.emp_no, s.salary from salaries as s  
    left outer join salaries as s2
    on s.emp_no = s2.emp_no 
    and s.salary < s2.salary
    where s2.emp_no is null
) salaries on salaries.emp_no = e.emp_no 
inner join (
    select t.emp_no, t.title from titles as t  
    left outer join titles as t2
    on t.emp_no = t2.emp_no 
    and t.to_date < t2.to_date 
    where t2.emp_no is null
) titles on titles.emp_no = e.emp_no
order by salaries.salary desc
limit 10;

基本上,由于 employees 与头衔和薪水之间存在一对多关系,因此我必须将 salariestitles 按其最新最大值分组,因为 salaries 它将是 salary 列,对于 titles 它将是 to_date 列。

SQL 工作完美,但它太慢了 ~ 即使在创建一些索引之后也是如此。

create index salary_emp_no_index on salaries (salary, emp_no);
create unique index emp_first_last_name_index on employees (emp_no, first_name, last_name, gender);
create index titles_emp_title on titles (emp_no, title)

我这里做错了什么?还有改进的余地吗?

编辑(添加 sqlfiddle)

http://sqlfiddle.com/#!9/72111d/1

两点:

首先,要获得每个 emp_no 的最高薪水并限制为 10,您根本不需要子查询或连接,您可以简单地执行(未测试):

select emp_no, max(salary) max_salary
from salaries
group by emp_no
order by max_salary desc
limit 10

其次,您只需要那(最多)10 名员工的头衔,因此将您的 max salary 查询用作 cte 或子查询,并且只查找这些员工的头衔,这应该会快得多。此外,您可以使用 https://whosebug.com/a/15422121/17389.

中的方法避免标题上的 self-join