我正在尝试优化查询。
我的问题似乎与MySQL, Union ALL and LIMIT类似,答案可能相同(我害怕)。但是在我的情况下,有一个更严格的限制(1)以及日期时间列的索引。
所以我们走了:
为简单起见,我们只有一个包含三个的表:列:
有一个索引(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吗?
或者唯一的选择是存储过程吗?
答案 0 :(得分:0)
答案 1 :(得分:0)
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上的复合指数是否有帮助;你需要尝试一下。
答案 2 :(得分:0)
在您的情况下,最有效的解决方案可能是在(md5, lastupdated)
上构建索引。此索引应该用于非常有效地解析每个子查询(查找索引中的值,然后查找一个数据页)。
不幸的是,当存在重复的lastupdated值时,Gavin引用的groupwise max将产生多行(诚然,在您的情况下可能不是一个问题)。
实际上,有一种使用group_concat
和substring_index
获得此答案的MySQL方式:
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