Улучшение производительности SQL-запросов на MySQL - PullRequest
0 голосов
/ 17 мая 2019

У меня есть SQL-запрос с десятью запросами.Поэтому я хочу избежать этих союзов из-за потребления ресурсов.В этом примере я просто показываю одно объединение.

  SELECT *
    FROM (  SELECT sv.SubmissionId,
                   sv1.FieldValue Etablissement,
                   sv2.FieldValue Nom,
                   sv3.FieldValue Prenom,
                   sv4.FieldValue Fonction,
                   sv5.FieldValue Identification,
                   sv6.FieldValue NomFormation,
                   ''         Signature
              FROM dfmna_rsform_submission_values sv
                   INNER JOIN dfmna_rsform_submissions sub
                       ON sv.SubmissionId = sub.SubmissionId
                   LEFT JOIN dfmna_rsform_submission_values sv1
                       ON sv.SubmissionId = sv1.SubmissionId
                      AND sv1.FieldName = 'NomEtablissement-Individuelle'
                   LEFT JOIN dfmna_rsform_submission_values sv2
                       ON sv.SubmissionId = sv2.SubmissionId
                      AND sv2.FieldName = 'Nom-Individuelle'
                   LEFT JOIN dfmna_rsform_submission_values sv3
                       ON sv.SubmissionId = sv3.SubmissionId
                      AND sv3.FieldName = 'Prenom-Individuelle'
                   LEFT JOIN dfmna_rsform_submission_values sv4
                       ON sv.SubmissionId = sv4.SubmissionId
                      AND sv4.FieldName = 'Fonction-Individuelle'
                   LEFT JOIN dfmna_rsform_submission_values sv5
                       ON sv.SubmissionId = sv5.SubmissionId
                      AND sv5.FieldName = 'NumAdelirpps-Individuelle'
                   LEFT JOIN dfmna_rsform_submission_values sv6
                       ON sv.SubmissionId = sv6.SubmissionId
                      AND sv6.FieldName = 'Nom-Formation'
             WHERE sv.FormId = 4
               AND sub.confirmed = 1
          GROUP BY sv.SubmissionId
          UNION ALL
            SELECT sv.SubmissionId,
                   sv1.FieldValue Etablissement,
                   sv2.FieldValue Nom,
                   sv3.FieldValue Prenom,
                   sv4.FieldValue Fonction,
                   sv5.FieldValue Identification,
                   sv6.FieldValue NomFormation,
                   ''         Signature
              FROM dfmna_rsform_submission_values sv
                   INNER JOIN dfmna_rsform_submissions sub
                       ON sv.SubmissionId = sub.SubmissionId
                   LEFT JOIN dfmna_rsform_submission_values sv1
                       ON sv.SubmissionId = sv1.SubmissionId
                      AND sv1.FieldName = 'NomEtablissement-Continue'
                   LEFT JOIN dfmna_rsform_submission_values sv2
                       ON sv.SubmissionId = sv2.SubmissionId
                      AND sv2.FieldName = 'Stg-Nom-Continue'
                   LEFT JOIN dfmna_rsform_submission_values sv3
                       ON sv.SubmissionId = sv3.SubmissionId
                      AND sv3.FieldName = 'Stg-Prenom-Continue'
                   LEFT JOIN dfmna_rsform_submission_values sv4
                       ON sv.SubmissionId = sv4.SubmissionId
                      AND sv4.FieldName = 'Stg-Fonction-Continue'
                   LEFT JOIN dfmna_rsform_submission_values sv5
                       ON sv.SubmissionId = sv5.SubmissionId
                      AND sv5.FieldName = 'Stg-NumAdelirpps-Continue'
                   LEFT JOIN dfmna_rsform_submission_values sv6
                       ON sv.SubmissionId = sv6.SubmissionId
                      AND sv6.FieldName = 'Nom-Formation'
             WHERE sv.FormId = 4
               AND sub.confirmed = 1
          GROUP BY sv.SubmissionId) t
   WHERE t.Nom <> ''
     AND t.NomFormation = 'my_criteria'
ORDER BY t.Nom;

Так что я хочу тот же вывод, но я хочу другой способ написать этот запрос без объединения.Спасибо.

Ответы [ 3 ]

0 голосов
/ 19 мая 2019

Добро пожаловать в уродливый мир схем EAV (entity-attribute-value).(Я добавил тег, чтобы вы могли найти больше вопросов и ответов об этом.)

   LEFT JOIN dfmna_rsform_submission_values sv4
                   ON sv.SubmissionId = sv4.SubmissionId
                  AND sv4.FieldName = 'Fonction-Individuelle'

Таблица dfmna_rsform_submission_values нуждается в

PRIMARY KEY(SubmissionId, FieldName)

Вероятно, нет необходимости в AUTO_INCREMENT.

Мой предложенный PK поможет производительности немного .Но EAV по своей сути является проблемой.

Другая проблема ... Вы действительно имели в виду LEFT?Это означает, что атрибут является необязательным.

         WHERE sv.FormId = 4
           AND sub.confirmed = 1

Поскольку INDEX не может охватывать две таблицы, это трудно оптимизировать.Было бы разумно переместить один из этих столбцов в другую таблицу?

      GROUP BY sv.SubmissionId

, возможно, «неправильно». Посмотрите ONLY_FULL_GROUP_BY.

WHERE t.Nom <> ''
  AND t.NomFormation = 'my_criteria'

собрали ли вы много строкТолько чтобы потом отфильтровать некоторые из них.Сложите их во внутреннее SELECTs.

Как только вы все это сделаете, давайте сделаем еще один проход.Но, пожалуйста, укажите SHOW CREATE TABLE и EXPLAIN SELECT ... Вероятно, потребуется составной индекс, необходимый для помощи с NomFormation = 'my_criteria'.

0 голосов
/ 19 мая 2019

Другая альтернатива ... и я ненавижу расширенные значения записей, связанные с полями, но эй, если это то, что у вас есть, пусть будет так.Я бы на самом деле настроил этот запрос, чтобы присоединиться к каждому обязательному компоненту, как вы это делали для «sub» Confirmed = 1, без проблем.Тогда я бы добавил ваше "dfmna_rsform_submission_values" ТАКЖЕ как ВНУТРЕННЕЕ СОЕДИНЕНИЕ на 'Nom-Formation' И ЗНАЧЕНИЕ, равное какому бы ни был ваш критерий.

Если представление не соответствует этому, кого это волнует, пропустите любую записьи у вас останутся только те, кто прошел предварительную квалификацию.

ТОГДА я бы сделал ОДНОЗНАЧНОЕ левое соединение с "dfmna_rsform_submission_values" после левого соединения с идентификатором представления независимо от дополнительных полей.

Применив MAX (case / when) к отдельным значениям поля, которые вы ищете, он вернет только это описание для этого представления столбца.

Выполнение Group By для представления вернет одну запись для каждого представления.

Просто альтернатива ..

SELECT 
      sv.SubmissionId,
      max( case when sv1.FieldName IN ( 'NomEtablissement-Individuelle', 'NomEtablissement-Continue' )
                then sv1.FieldValue else '' end ) Etablissement,
      max( case when sv1.FieldName IN ( 'Nom-Individuelle', 'Stg-Nom-Continue' )
                then sv1.FieldValue else '' end ) Nom,
      max( case when sv1.FieldName IN ( 'Prenom-Individuelle', 'Stg-Prenom-Continue' )
                then sv1.FieldValue else '' end ) Prenom,
      max( case when sv1.FieldName IN ( 'Fonction-Individuelle', 'Stg-Fonction-Continue' )
                then sv1.FieldValue else '' end ) Fonction,
      max( case when sv1.FieldName IN ( 'NumAdelirpps-Individuelle', 'Stg-NumAdelirpps-Continue' )
                then sv1.FieldValue else '' end ) Identification,
      max( case when sv1.FieldName = 'Nom-Formation'
                then sv1.FieldValue else '' end ) NomFormation,
      max( '' ) Signature
   FROM 
      dfmna_rsform_submission_values sv
         INNER JOIN dfmna_rsform_submissions sub
            ON sv.SubmissionId = sub.SubmissionId
           AND sub.confirmed = 1

         INNER JOIN dfmna_rsform_submission_values svRequired
            ON sv.SubmissionId = svRequired.SubmissionId
            AND svRequired.FieldName = 'Nom-Formation'
            AND svRequired.FieldValue = 'my_criteria'

         LEFT JOIN dfmna_rsform_submission_values sv1
            ON sv.SubmissionId = sv1.SubmissionId
   WHERE 
      sv.FormId = 4
   GROUP BY 
      sv.SubmissionId
   HAVING
      max( case when sv1.FieldName IN ( 'Nom-Individuelle', 'Stg-Nom-Continue' )
                then sv1.FieldValue else '' end ) <> ''      
   ORDER BY 
      max( case when sv1.FieldName IN ( 'Nom-Individuelle', 'Stg-Nom-Continue' )
                then sv1.FieldValue else '' end )
0 голосов
/ 17 мая 2019

вы можете переписать его как

SELECT sv.SubmissionId,
sv.FieldValue,
''         Signature
FROM dfmna_rsform_submission_values sv INNER JOIN dfmna_rsform_submissions sub  ON sv.SubmissionId = sub.SubmissionId 
WHERE
sv.FieldName in ('NomEtablissement-Individuelle', 'Nom-Individuelle', 'Prenom-Individuelle', 'Fonction-Individuelle', 'NumAdelirpps-Individuelle', 'Nom-Formation')
AND sv.FormId = 4
AND sub.confirmed = 1
GROUP BY sv.SubmissionId

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...