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
是最后一个,因为它不涉及WHERE
或ORDER BY
,而只是有'covering'。 (参见 EXPLAIN
中的 "Using index"。)
如果您的变体涉及日期范围而不是单个 saleDate
,那么我所说的 所有 都需要修改以针对它进行优化。一些原则将继续存在,但索引将不会。
我的服务器是 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
是最后一个,因为它不涉及WHERE
或ORDER BY
,而只是有'covering'。 (参见 EXPLAIN
中的 "Using index"。)
如果您的变体涉及日期范围而不是单个 saleDate
,那么我所说的 所有 都需要修改以针对它进行优化。一些原则将继续存在,但索引将不会。