繁体   English   中英

MySQL优化UNION查询

[英]MySQL Optimize UNION query

我正在尝试优化查询。

我的问题似乎与MySQL,Union ALL和LIMIT相似答案可能相同(恐怕)。 但是在我的情况下,有一个更严格的限制(1)以及datetime列上的索引。

所以我们开始:

为了简单起见,让我们只有一个表,其中包含三个:列:

  • md5(varchar)
  • 值(varchar)。
  • 最后更新(日期时间)

上有一个索引(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。 您确实想要每个键的分组最大值,并具有自定义顺序。

分组最大

按FIELD()排序

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_concatsubstring_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM