提高MySQL上的SQL查询性能

时间:2019-05-17 08:28:57

标签: mysql sql performance entity-attribute-value

我有一个带有十个查询并集的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 :(得分:0)

您可以将其重写为

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

答案 1 :(得分:0)

欢迎来到EAV(实体-属性-值)架构的丑陋世界。 (我添加了一个标签,以便您可以找到更多有关此问题的问答。)

   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将有助于表现 some 。但是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 TABLEEXPLAIN SELECT ...,可能需要一个综合索引来帮助NomFormation = 'my_criteria'

答案 2 :(得分:0)

另一种选择...而且我讨厌与字段相关的扩展记录值,但是,如果这就是您所拥有的,那就这样吧。我实际上将调整此查询以将每个必需的组件连接起来,就像“ sub” Confirmed = 1时那样,没问题。然后,我也将“ dfmna_rsform_submission_values”添加为“ Nom-Formation”上的INNER JOIN,并且其值等于您的标准。

如果提交的内容不符合条件,那么谁在乎,请跳过任何记录,而您只剩下那些预先合格的记录。

一旦我在提交ID上左连接后,无论是否有其他字段,我都会对“ dfmna_rsform_submission_values”进行左连接。

通过在要查找的各个字段值上应用MAX(case / when),它将仅返回该列表示形式的描述。

对提交内容进行分组依据将为每个提交内容返回一条记录。

只是一种选择。

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 )