SQL Query真的很慢,如何改进?

时间:2016-01-26 15:52:11

标签: mysql sql

编辑:似乎问题在于help_file表,它包含每次选择表时加载的.pdf文件的实际二进制数据,有没有办法绕过这个?我不想每次都加载所有数据。

我不是那么精通SQL-Queries的运行时效率,但是这个查询非常慢并且需要大约两秒钟才能执行。

SELECT
  id,
  display_name,
  NAME,
  document_id,
  chapter,
  aenderung_datum,
  DATA,
  file_attached,
  right_group,
  role,
  partner,
  sequence_nr
FROM
  (SELECT
    hf.id,
    hf.display_name,
    hf.name,
    hf.document_id,
    hf.aenderung_datum,
    DATA,
    LENGTH(DATA) > 0 AS file_attached,
    GROUP_CONCAT(
      DISTINCT (
        IF(
          b.name IS NULL,
          a.right_group_id,
          b.name
        )
      )
      ORDER BY a.right_group_id
    ) AS right_group,
    GROUP_CONCAT(
      DISTINCT (
        IF(
          role.name IS NULL,
          role_id,
          role.name
        )
      )
      ORDER BY role_id
    ) AS role,
    GROUP_CONCAT(
      DISTINCT (IF(ch.name IS NULL, '-', ch.name))
      ORDER BY a.chapter_id
    ) AS chapter,
    GROUP_CONCAT(
      DISTINCT (
        IF(c.name IS NULL, partner_id, c.name)
      )
      ORDER BY partner_id
    ) AS partner,
    GROUP_CONCAT(
      DISTINCT a.sequence_nr
      ORDER BY a.sequence_nr
    ) AS sequence_nr
  FROM
    db_release_osp.help_file hf
    LEFT JOIN db_release_osp.help_file_assign AS a
      ON help_file_id = hf.id
    LEFT JOIN cdb_admin_osp.right_group AS b
      ON a.right_group_id = b.id
    LEFT JOIN cdb_admin_osp.role
      ON a.role_id = role.id
    LEFT JOIN db_release_osp.help_chapter AS ch
      ON a.chapter_id = ch.id
    LEFT JOIN cdb_osp_admin.partner AS c
      ON partner_id = c.id
  GROUP BY hf.id
  ORDER BY hf.id) AS overview_table

有什么大瑕疵可以忽略吗?我怎样才能减少花费的时间?

我想使用临时表可能是一种解决方案。

2 个答案:

答案 0 :(得分:2)

首先,您的外部查询返回内部查询的确切结果,但字段的顺序除外(章节)。如果您明确地需要它,我会将章节字段移动到预期位置,然后删除冗余的外部查询。

SELECT
      hf.id,
      hf.display_name,
      hf.name,
      hf.document_id,
      GROUP_CONCAT( DISTINCT (IF(ch.name IS NULL, 
         '-', ch.name))
         ORDER BY a.chapter_id ) AS chapter,
      hf.aenderung_datum,
      DATA,
      LENGTH(DATA) > 0 AS file_attached,
      GROUP_CONCAT( DISTINCT ( IF( b.name IS NULL,
         a.right_group_id, b.name )) 
         ORDER BY a.right_group_id ) AS right_group,
      GROUP_CONCAT( DISTINCT ( IF( role.name IS NULL,
         a.role_id, role.name ))
         ORDER BY a.role_id ) AS role,
      GROUP_CONCAT( DISTINCT ( IF(c.name IS NULL, 
         a.partner_id, c.name))
         ORDER BY a.partner_id ) AS partner,
      GROUP_CONCAT( DISTINCT a.sequence_nr 
         ORDER BY a.sequence_nr ) AS sequence_nr
   FROM
      db_release_osp.help_file hf
         LEFT JOIN db_release_osp.help_file_assign AS a
            ON hf.id = a.help_file_id
            LEFT JOIN cdb_admin_osp.right_group AS b
               ON a.right_group_id = b.id
            LEFT JOIN cdb_admin_osp.role
               ON a.role_id = role.id
            LEFT JOIN db_release_osp.help_chapter AS ch
               ON a.chapter_id = ch.id
            LEFT JOIN cdb_osp_admin.partner AS c
               ON partner_id = c.id
   GROUP BY 
      hf.id
   ORDER BY 
      hf.id

接下来,我会在表格上提供以下索引,以帮助他们“#34;覆盖"索引。这样,它可以直接从索引中获取id和名称(或其他部分),而无需转到查找表值的原始数据页。

table             index
help_file         (id)
right_group       (id, name )
role              (id, name )
help_chapter      (id, name )
partner           (id, name )
help_file_assign  (help_file_id, right_group_id, role_id, chapter_id, partner_id )
-- Note: Due to lack of alias on your left-join to the partner table
-- alias "c", it APPEARS the "Partner_ID" column is from your 
-- help_file_assign table.  If other, please adjust, but also fix the
-- alias reference for clarification.

如果性能仍然悬在你身上,你可能想再添加一个关键字,因为它告诉MySQL完全按照它呈现的方式运行查询。

SELECT STRAIGHT_JOIN  (rest of query)

答案 1 :(得分:0)

我怀疑连接具有大型二进制列的表会消耗大量内存。我已将DATA,file_attached和aenderung_datum移到单独的join子句中。

SELECT
  overview_table.id,
  display_name,
  NAME,
  document_id,
  chapter,
  aenderung_datum,
  DATA,
  file_attached,
  right_group,
  role,
  partner,
  sequence_nr
FROM
  (SELECT
    hf.id,
    hf.display_name,
    hf.name,
    hf.document_id,
    GROUP_CONCAT(
      DISTINCT (
        IF(
          b.name IS NULL,
          a.right_group_id,
          b.name
        )
      )
      ORDER BY a.right_group_id
    ) AS right_group,
    GROUP_CONCAT(
      DISTINCT (
        IF(
          role.name IS NULL,
          role_id,
          role.name
        )
      )
      ORDER BY role_id
    ) AS role,
    GROUP_CONCAT(
      DISTINCT (IF(ch.name IS NULL, '-', ch.name))
      ORDER BY a.chapter_id
    ) AS chapter,
    GROUP_CONCAT(
      DISTINCT (
        IF(c.name IS NULL, partner_id, c.name)
      )
      ORDER BY partner_id
    ) AS partner,
    GROUP_CONCAT(
      DISTINCT a.sequence_nr
      ORDER BY a.sequence_nr
    ) AS sequence_nr
  FROM
    db_release_osp.help_file hf
    LEFT JOIN db_release_osp.help_file_assign AS a
      ON help_file_id = hf.id
    LEFT JOIN cdb_admin_osp.right_group AS b
      ON a.right_group_id = b.id
    LEFT JOIN cdb_admin_osp.role
      ON a.role_id = role.id
    LEFT JOIN db_release_osp.help_chapter AS ch
      ON a.chapter_id = ch.id
    LEFT JOIN cdb_osp_admin.partner AS c
      ON partner_id = c.id
  GROUP BY hf.id
  ORDER BY hf.id) AS overview_table
LEFT JOIN
  (SELECT
    id,
    DATA,
    LENGTH(DATA) > 0 AS file_attached,
    aenderung_datum
    FROM db_release_osp.help_file) AS data_table
  ON data_table.id = overview_table.id