How do you optimize a MySQL query that joins on itself and does a “custom” group by?

半世苍凉 提交于 2019-12-13 06:09:09

问题


I have the following query that is starting to become slow as the size of the DB table increases:

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

First, I am selecting everything from Translations, joined with itself to get me the corresponding English value also.

Then, I then want to limit my results to only one per PropertyKey. This is like a group by except I need to pick a specific record to be the one returned (instead of the way group by just gives me the first one it finds). That is why I have the inner query that just returns one TranslationId.

When I run explain I get the following info:

Is there a way I can return the same set of results without having to have MySQL use a slower derived table? Thanks!

UPDATE: I created an SQL Fiddle with a schema and sample data. You can run my query for yourself to see the results it gives. I need to be able to get the same results, hopefully in a faster way. http://sqlfiddle.com/#!2/44eb0/3/0


回答1:


I think you want the most recent TranslatedValue for the given local and priority that matches PropertyKey in a record.

If so, the following does what you want, using a single correlated subquery:

 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;

(The having clause eliminates records with no translation.)

If so, then an index on Translations(PropertyKey, Locale, Priority, ModifiedDate) should speed up the query.



来源:https://stackoverflow.com/questions/16465448/how-do-you-optimize-a-mysql-query-that-joins-on-itself-and-does-a-custom-group

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!