SQL 永远查询 我的查询格式是否正确?

SQL Query taking forever is my query properly formatted?

我的服务器是 DigitalOcean VPS,我有 60G 硬盘、4G 内存、4G 交换文件,并通过 mysql workbench 连接到 1Gig 互联网连接。下面的查询在我取消之前花费了 30 多分钟。许多查询需要 1-2 分钟,我觉得对于查询的简单性来说太长了。此查询可能未优化。有没有办法优化查询?如何优化查询速度?

(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 10 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 11 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 20 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 21 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 27
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 30 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 40
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 50 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 60 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 70 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 80
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 81 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 82 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 90
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 95 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 96 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 1 AND departmentNumber = 97 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 10 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 11 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 20 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 21 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 27
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 30 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 40
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 50 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 60 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 70 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 80
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 81 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 82 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 90
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 95 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 96 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 3 AND departmentNumber = 97 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 10 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 11 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 20 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 21 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 27
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 30 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 40
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 50 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 60 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 70 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 80
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 81 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 82 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 90
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 95 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 96 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 10 AND departmentNumber = 97 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 10 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 11 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 20 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 21 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 27
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 30 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 40
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 50 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 60 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 70 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 80
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 81 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 82 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 90
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 95 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 96 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 11 AND departmentNumber = 97 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 10 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 11 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 20 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 21 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 27
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 30 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 40
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 50 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 60 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 70 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 80
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 81 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 82 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 90
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 95 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 96 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 16 AND departmentNumber = 97 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 10 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 11 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 20 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 21 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 27
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 30 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 40
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 50 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 60 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 70 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 80
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 81 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 82 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 90
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 95 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 96 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 17 AND departmentNumber = 97 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 10 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 11 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 20 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 21 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 27
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 30 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 40
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 50 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 60 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 70 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 80
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 81 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 82 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 90
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 95 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 96 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 18 AND departmentNumber = 97 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 10 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 11 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 20 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 21 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 27
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 30 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 40
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 50 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 60 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 70 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 80
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 81 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 82 
order by unitsSold desc
limit 30)
union all
(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 90
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 95 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 96 
order by unitsSold desc
limit 30)
union all(select *
from movement
where saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day) AND StoreNumber = 19 AND departmentNumber = 97 
order by unitsSold desc
limit 30);

总而言之:有将近 300 个 UNIONd 在一起:

        SELECT  *
            from  movement
            where  saleDate = date_sub(curdate(), interval WEEKDAY(curdate()) day)
              AND  StoreNumber =       -- some number
              AND  departmentNumber =  -- some other number
            order by  unitsSold desc
            limit  30

看起来您的查询可以描述为:前 30 行 unitsSold 每个 StoreNumber & departmentNumber

我会这样写:

SELECT t.*
FROM (
    SELECT m.*, 
      IF(@s=StoreNumber AND @d=departmentNumber, @r:=@r+1, @r:=1) AS rowNumber,
      @s:=StoreNumber AS StoreNumber, 
      @d:=departmentNumber AS departmentNumber
    FROM (@g:=0, @r:=0) AS _init
    CROSS JOIN movement AS m
    WHERE saleDate = CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY
    ORDER BY StoreNumber DESC, departmentNumber DESC, unitsSold DESC
) AS t
WHERE t.rowNumber <= 30;

确保在 table 列上有一个索引:

ALTER TABLE movement ADD KEY (saleDate, StoreNumber, departmentNumber, unitsSold);

这是 MySQL 中很常见的模式,因为 MySQL 不支持 SQL 窗口函数。

(注意我没有测试上面的查询)

另请参阅我对 How to SELECT the newest four items per category?

的回答

我的第一条评论是添加复合 INDEX(saleDate, StoreNumber, departmentNumber) -- 以任何顺序。

但是,深入挖掘,我发现了其他问题。

不做SELECT *,只做SELECT id(假设id就是PRIMARY KEY),然后用大联合乱七八糟的子查询来查找您需要的任何其他列。要完成这项工作,您需要这个 covering 索引 而不是 我上面推荐的索引:INDEX(saleDate, StoreNumber, departmentNumber, unitsSold, id).

问题:这看起来像一个子查询;整个查询是否类似于

SELECT *
        FROM ( that union mess ) AS u
    ORDER BY unitsSold DESC
    LIMIT 30

如果是这样,那就是更改为

的最佳时机
SELECT m.*
        FROM ( that union mess, but with only `id` ) AS u
        JOIN movement AS m  USING (id)
    ORDER BY m.unitsSold DESC
    LIMIT 30

但是,更好的是尽早完成 LIMIT

SELECT m.*
    FROM ( SELECT id
            FROM ( that union mess, but with only `id` ) AS u
            ORDER BY unitsSold DESC
            LIMIT 30 )
    JOIN movement AS m  USING (id)
    ORDER BY unitsSold DESC

这个版本只需要获取整整 30 行,而不是之前的情况下的 278*30。

一旦理解了我的建议,请返回使用 IN 看看它是否足够好:

SELECT m.*
    FROM ( SELECT id
            FROM  movement
            WHERE  saleDate = CURDATE() - INTERVAL WEEKDAY(curdate()) DAY
              AND  StoreNumber      IN (...)
              AND  departmentNumber IN (...)
            order by  unitsSold desc
            limit  30 )
    JOIN movement AS m  USING (id)
    ORDER BY unitsSold DESC

由于很难预测哪个索引是最好的,我推荐多个覆盖索引供优化器选择:

INDEX(saleDate, StoreNumber, departmentNumber, unitsSold, id)
INDEX(saleDate, unitsSold, departmentNumber, StoreNumber, id)

saleDate 是第一个,因为它是唯一的 =id是最后一个,因为它不涉及WHEREORDER BY,而只是有'covering'。 (参见 EXPLAIN 中的 "Using index"。)

如果您的变体涉及日期范围而不是单个 saleDate,那么我所说的 所有 都需要修改以针对它进行优化。一些原则将继续存在,但索引将不会