您如何优化连接自身并执行“自定义”分组的 MySQL 查询?
Posted
技术标签:
【中文标题】您如何优化连接自身并执行“自定义”分组的 MySQL 查询?【英文标题】:How do you optimize a MySQL query that joins on itself and does a "custom" group by? 【发布时间】:2013-05-04 03:29:53 【问题描述】:随着数据库表大小的增加,我的以下查询开始变慢:
SELECT
t.*,
e.TranslatedValue AS EnglishValue
FROM (
SELECT DISTINCT PropertyKey
FROM Translations
) grouper
JOIN Translations t
ON t.TranslationId = (
SELECT TranslationId
FROM Translations gt
WHERE gt.PropertyKey = grouper.PropertyKey
AND gt.Locale = 'es'
AND gt.Priority = 3
ORDER BY gt.ModifiedDate DESC
LIMIT 1
)
INNER JOIN Translations e
ON t.EnglishTranslationId = e.TranslationId
ORDER BY t.ReviewerValidated, PropertyKey
首先,我从 Translations 中选择所有内容,并将其与自身相结合,以获得相应的英文值。
然后,我想将结果限制为每个 PropertyKey 一个。这就像一个 group by,除了我需要选择一个特定的记录作为返回的记录(而不是 group by 只给我它找到的第一个记录)。这就是为什么我有只返回一个 TranslationId 的内部查询。
当我运行解释时,我得到以下信息:
有没有一种方法可以返回相同的结果集,而不必让 mysql 使用较慢的派生表?谢谢!
更新:我创建了一个带有架构和示例数据的 SQL Fiddle。你可以 自己运行我的查询以查看它给出的结果。我需要成为 能够获得相同的结果,希望以更快的方式。 http://sqlfiddle.com/#!2/44eb0/3/0
【问题讨论】:
你能提供样本数据和你想要的结果吗? MySQL 应该在你执行查询时报错,因为ORDER BY
子句中的 PropertyKey 是不明确的(有三个,即使它们相等)。
@newtover - 它不会抱怨,因为该级别只有一个 PropertyKey(其他的在子查询中)。如果你想坚持一个t。为了清楚起见,在它前面,这很好。
@GordonLinoff 感谢您提供查看示例数据和结果。有没有办法将文件附加到 SO 问题?有没有类似 JSFiddle for MySQL 的服务?
@GordonLinoff 我用我需要的模式、数据和结果创建了一个 SQL Fiddle:sqlfiddle.com/#!2/44eb0/3/0
【参考方案1】:
我认为您想要与记录中的PropertyKey
匹配的给定本地和优先级的最新TranslatedValue
。
如果是这样,以下是您想要的,使用单个相关子查询:
select t.*,
(select t2.TranslatedValue
from Translations t2
where t.PropertyKey = t2.PropertyKey and
t2.Locale = 'es' and
t2.Priority = 3
order by t.ModifiedDate desc
limit 1
) as EnglishValue
from Translations t
having EnglishValue is not NULL
ORDER BY t.ReviewerValidated, PropertyKey;
(having
子句删除没有翻译的记录。)
如果是这样,那么Translations(PropertyKey, Locale, Priority, ModifiedDate)
上的索引应该会加快查询速度。
【讨论】:
感谢@Gordon Linoff,但我仍然没有得到我需要的东西。我首先必须稍微更改您的查询:t2.Locale = 'es' 和 t2.Priority = 3 应该更改为 t.Locale = 'es' 和 t.Priority = 3。我还必须添加 where t2.Locale = 'en' 因为我在 EnglishValue 字段中获得了各种语言。现在数据和我的查询完全一样,除了 PropertyKey 上还有重复。 @11101101b 。 . .当然,PropertyKey
上有重复项。您没有进行最终分组。如果这是您想要的输出,您可以添加 group by PropertyKey
。
我试过@Gordon Linoff,但你必须在拥有和订购之前进行分组(这并没有给我我想要的)。
我创建了一个 SQL Fiddle。我用指向 Fiddle 的链接修改了我的问题(允许您对我的示例模式和数据实际运行查询)。我也有一个尝试实现您的查询的小提琴(sqlfiddle.com/#!2/44eb0/6/0)。如您所见,结果并不相同。以上是关于您如何优化连接自身并执行“自定义”分组的 MySQL 查询?的主要内容,如果未能解决你的问题,请参考以下文章
如何正确连接并显示从 Firebase 到自定义列表视图 Android Studio 的数据
如何按字段对文档进行分组并使用带有 CouchDB 视图的自定义 reduce 函数列出不相等的值