[英]MySQL Optimize UNION query
我正在尝试优化查询。
我的问题似乎与MySQL,Union ALL和LIMIT相似,答案可能相同(恐怕)。 但是在我的情况下,有一个更严格的限制(1)以及datetime列上的索引。
所以我们开始:
为了简单起见,让我们只有一个表,其中包含三个:列:
上有一个索引(md5,已更新),因此选择md5键,按更新顺序排序并限制为1将会得到优化。
搜索将返回最多一个与10个md5键之一匹配的记录。 键具有优先级。 因此,如果有prio 1的记录,则优先于prio 2、3等的任何记录。
当前使用UNION ALL:
select * from
(
(
select 0 prio, value
from mytable
where md5 = '7b76e7c87e1e697d08300fd9058ed1db'
order by lastupdated desc
limit 1
)
union all
(
select 1 prio, value
from mytable
where md5 = 'eb36cd1c563ffedc6adaf8b74c259723'
order by lastupdated desc
limit 1
)
) x
order by prio
limit 1;
它可以工作,但是如果提供了10个键,UNION似乎会执行所有10个查询。
但是,从业务角度来看,可以顺序运行选择并在第一个匹配项后停止运行。
通过普通的SQL是否有可能?
还是唯一的选择是存储过程?
UNION ALL
的优化器无法确定您的工作。
我不知道是否可以这样做,但是假设您有一个md5prio表,其中包含您要查找的哈希码列表。 例如。
prio md5
0 '7b76e7c87e1e697d08300fd9058ed1db'
1 'eb36cd1c563ffedc6adaf8b74c259723'
etc
在里面。
那么您的查询可能是:
select mytable.*
from mytable
join md5prio on mytable.md5 = md5prio.md5
order by md5prio.prio, mytable.lastupdated desc
limit 1
这样可以保存重复的查询。 您肯定需要在mytable.md5上建立索引。 我不确定您对lastupdated的复合索引是否会有所帮助; 您需要尝试一下。
在您的情况下,最有效的解决方案可能是在(md5, lastupdated)
上建立索引。 该索引应用于非常有效地解析每个子查询(查找索引中的值,然后查找一个数据页)。
不幸的是,当有重复的lastupdated值时,Gavin引用的groupwise max将产生多行(诚然,在您的情况下可能不必担心)。
实际上,有一种MySQL方法使用group_concat
和substring_index
来获得此答案:
select p.prio,
substring_index(group_concat(mt.value order by mt.lastupdated desc), ',', 1)
from mytable mt join
(select 0 as prio, '7b76e7c87e1e697d08300fd9058ed1db' as md5 union all
select 1 as prio, 'eb36cd1c563ffedc6adaf8b74c259723' as md5 union all
. . .
) p
on mt.md5 = p.md5
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.