Как вы оптимизируете MySQL-запрос, который присоединяется к себе и выполняет "обычную" группу?

У меня есть следующий запрос, который начинает замедляться по мере увеличения размера таблицы БД:

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. Это похоже на группу, за исключением того, что мне нужно выбрать конкретную запись, которая будет возвращена (вместо того, чтобы группа просто дала мне первую, которую она обнаружила). Вот почему у меня есть внутренний запрос, который просто возвращает один TranslationId.

Когда я запускаю объяснение, я получаю следующую информацию:

enter image description here

Есть ли способ вернуть один и тот же набор результатов без необходимости использования MySQL более медленной производной таблицы? Спасибо!

UPDATE. Я создал скрипт SQL со схемой и образцами данных. Ты можешь запустите мой запрос для себя, чтобы увидеть результаты, которые он дает. мне нужно быть способный получить те же результаты, надеюсь, быстрее. http://sqlfiddle.com/#!2/44eb0/3/0

Ответ 1

Я думаю, вам нужен самый последний TranslatedValue для данного локального и приоритетного, который соответствует PropertyKey в записи.

Если да, то выполняется то, что вы хотите, используя один коррелированный подзапрос:

 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) должен ускорить запрос.