mysql在特定阈值下获取最大值的最快方法
我在 mysql 中有两个表和一个慢速查询。
表格:
包含通道、开始时间、结束时间
- 字段的表格剪辑
包含通道、开始时间、结束时间字段的表格显示
包含通道、开始时间、结束时间
两个表都有字段 start_time 的索引。
我正在尝试查找许多剪辑中在剪辑之前开始的节目。
到目前为止,我得到了这个查询:
SELECT (
SELECT shows.id
FROM shows
WHERE shows.starttime<=clips.starttime AND shows.channel=clips.channel
ORDER BY shows.starttime DESC
LIMIT 1) as show_id,
clips.*
FROM clips
对于少量的剪辑,这效果很好,但对于大量的剪辑,它变得太慢。
我的理解是,依赖子查询应该特别快,因为 start_time 上有一个索引,并且需要做的只是索引查找。尽管如此,它还是很慢,并且解释查询状态是“使用where”而不是“使用索引”。
这是解释的输出
--+------------------+-----+-----+------------+---------+------+----+------+-----------------------+
id| select_type |table|type |possibleKeys| key |keylen|ref |rows | Extra |
--+------------------+-----+-----+------------+---------+------+----+------+-----------------------+
1|PRIMARY |clips|range| startDate |startDate| 8 |NULL| 9095 |Using where;Using index|
2|DEPENDENT SUBQUERY|shows|index| startDate |startDate| 8 |NULL|287896|Using where;Using index|
--+------------------+-----+-----+------------+---------+------+----+------+-----------------------+
任何有关如何提高此任务性能的建议将不胜感激。
I've got two tables and a slow query in mysql.
The tables:
Table clips with fields channel,start_time,end_time
Table shows with fields channel,start_time,end_time
both tables have indeces for field start_time.
I am trying to find the show that started just before the clip for many clips.
So far I've got this query:
SELECT (
SELECT shows.id
FROM shows
WHERE shows.starttime<=clips.starttime AND shows.channel=clips.channel
ORDER BY shows.starttime DESC
LIMIT 1) as show_id,
clips.*
FROM clips
For a small number of clips this works great but for large number of clips it gets too slow.
My understanding would be that the dependent subquery should be extra fast since there is an index on start_time and all that needs to be done is an index lookup. Nevertheless it is slow and explaining the query states "using where" instead of "using index".
Here is the output of explain
--+------------------+-----+-----+------------+---------+------+----+------+-----------------------+
id| select_type |table|type |possibleKeys| key |keylen|ref |rows | Extra |
--+------------------+-----+-----+------------+---------+------+----+------+-----------------------+
1|PRIMARY |clips|range| startDate |startDate| 8 |NULL| 9095 |Using where;Using index|
2|DEPENDENT SUBQUERY|shows|index| startDate |startDate| 8 |NULL|287896|Using where;Using index|
--+------------------+-----+-----+------------+---------+------+----+------+-----------------------+
Any suggestions on how to improve performace for this task would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试将查询重写为
因为剪辑是节目的一部分,所以您希望它们靠近在一起,您可以通过执行以下操作进一步限制命中数:
这将阻止 MySQL 运行对每一行进行排序的完整子查询的剪辑。
Try to rewrite the query as
Because clips are part of a show, you would expect them to be close together, you can limit the number of hits further by doing something like:
This will prevent MySQL from running a full subquery with sort on every row of clips.
我认为添加同时使用
start_time
和channel
列的索引可能会将查询性能提高到可接受的值。约翰的回答很好,但考虑到你的过滤器,我认为索引在任何情况下都可以提高性能。
I think adding an index that uses both
start_time
andchannel
columns may improve the query performance to an acceptable value.Johan's answer is great, but given your filters I think the index may improve the performance in any case.