这两者之间的最佳查询是什么?他们输出相同的结果,期望一个在where in中执行条件,另一个在inner join中执行条件。
select uv.* from version v inner join user_version uv ON v.id=uv.version_id
WHERE (v.number, v.master_id) IN (
select max(v.number) as number, v.master_id
from version v inner join user_version uv ON v.id=uv.version_id group by v.master_id);和
select * from user_version uv
inner join version v on v.id=uv.version_id and v.number
inner join (
select uv2.user_id, max(v2.number) maxNumber, v2.master_id master_id, v2.id version_id from version v2
inner join user_version uv2 on v2.id=uv2.version_id group by v2.master_id ) test
on test.master_id=v.master_id and test.maxNumber=v.number ;我用一个例子创建了一个sqlfiddle:http://sqlfiddle.com/#!2/76001/62 (这个想法是获取与给定用户链接的“主”实体的最大版本)。
如果您有其他的想法(我使用mysql,所以我不能使用windows函数)
谢谢
发布于 2013-10-29 10:09:05
要回答这个问题并不容易。您应该知道一件重要的事情: MySQL将IN (<static values list>)和IN (<subquery>)视为不同查询。第一个等于范围比较(如.. OR = .. OR =),而第二个等于= ANY () -而且不一样。因此,简单地说:使用IN和子查询将导致ANY()查询,即使子查询独立并返回静态的值列表,MySQL也不会为此使用索引。悲伤,但却是真的。MySQL无法预测这一点,因此即使很明显,也不会使用索引。如果您要使用JOIN (即重写您的IN (<subquery>)),那么如果可能的话,MySQL将为JOIN条件使用索引。
现在,第二种情况可能是使用分区时的JOIN和IN。如果您要使用JOIN --很遗憾--但MySQL也无法在普通情况下预测JOIN的分区--而且它将使用整个分区集。将JOIN替换为IN (<static list>)将更改EXPLAIN PARTITION图片: MySQL将只使用在IN子句中指定的从范围中选择值所需的分区。但是,同样,这将不适用于IN (<subquery>)。
作为结论--当我们谈到MySQL如何处理IN子查询时,这是可悲的--在一般情况下,它不能安全地被JOIN取代(这是关于分区案例)。因此,常见的解决方案是:在应用程序级别将子查询与主查询分离。如果我们说的是独立的子查询,返回静态值列表,这是最好的建议--那么您可以将该值列表替换为IN(<static list>),并获得好处: MySQL将对其使用索引,如果我们说的是分区,那么将只使用它们实际需要的值。
https://stackoverflow.com/questions/19654878
复制相似问题