避免全索引扫描

Vad*_*dim 5 mysql query-optimization

我使用 MySQL 员工的测试数据库 - 测试数据库 我想优化查询

SELECT emp_no, SUM(salary)
FROM salaries
WHERE from_date < '1999-01-01'
group by emp_no;
Run Code Online (Sandbox Code Playgroud)

查询费用:287790

哪些索引可以帮助我?

我尝试使用emp_noandsalaryemp_noand创建索引from_date,但没有结果。有一个完整的扫描索引。

也尝试使用OVER(PARTITION BY)代替GROUP BY

SELECT emp_no, SUM(salary) OVER (PARTITION by emp_no)
FROM salaries  
WHERE from_date < '1999-01-01'; 
Run Code Online (Sandbox Code Playgroud)

OVER例如,避免完整索引扫描或使用GROUP BY

Ric*_*mes 3

这取决于您运行的版本。

旧版本: INDEX(from_date, emp_no, salary)是“覆盖”,将对部分索引进行“范围”扫描。但这GROUP BY可能涉及某种类型。

较新的版本: INDEX(emp_no, from_date, salary)也是“覆盖”,但可以跳过索引而不必触及每一行。这或许可以避免排序。

这是另一件事要测试:

SELECT emp_no,
       ( SELECT SUM(salary) FROM salaries
             WHERE emp_no = e.emp_no 
               AND from_date < '...')
    FROM employees AS e
Run Code Online (Sandbox Code Playgroud)

注意:我假设employees每个员工有一行,不像salaries?? 这种方法避免了GROUP BY,但具有相关子查询的开销。现在salaries需要INDEX(emp_no, from_date, salary)--按此顺序,并且每次在索引中进行较小范围的扫描。