mysql - 加快编译的 MySQL 查询(目前大约需要 15 秒)

标签 mysql join indexing

我是索引的新手,并不完全理解它,但是 - 我有所有使用索引的表,除了主要表 - '文章' 表('文章')。我没有那么多记录,但查询大约需要 15 秒(显然 Not Acceptable )。

我正在使用 CakePHP 构建查询,但我不确定这是否重要。

我试过为 slug 创建索引,为 id 创建索引,为 created,rank_id,id,blog 创建索引

但是 - 它不会使用任何这些。

文章解释表:(添加完整解释)

1   SIMPLE  Article ALL PRIMARY,id              1661    Using temporary; Using filesort
1   SIMPLE  Upload  ref model, foreign_key  model, foreign_key  38  const,myDB.Article.id   10  
1   SIMPLE  SiteArea    const   PRIMARY PRIMARY 4   const   1   Using index
1   SIMPLE  SiteAreasSiteSection    ref site area id    site area id    5   myDB.SiteArea.id    2   
1   SIMPLE  SiteAreasSiteSubSection ref site area id    site area id    5   myDB.SiteArea.id    2   
1   SIMPLE  SiteSection eq_ref  PRIMARY PRIMARY 4   myDB.SiteAreasSiteSection.site_section_id   1   Using index
1   SIMPLE  SiteSubSection  eq_ref  PRIMARY PRIMARY 4   myDB.SiteAreasSiteSubSection.site_sub_section_id    1   Using index
1   SIMPLE  RanksSiteArea   index       all 14      2   Using index
1   SIMPLE  ArticlesSiteSection ref site section id site section id 5   myDB.SiteSection.id 244 
1   SIMPLE  ArticlesSiteSubSection  ref site sub section id site sub section id 5   myDB.SiteSubSection.id  28  
1   SIMPLE  ArticlesSiteArea    index       all 19      1   Using where; Using index

查询:

SELECT
  Article.title,
  GROUP_CONCAT(
        `Upload`.`path`,
        `Upload`.`name`
  ORDER BY
        `Upload`.`featured` DESC
  )AS Uploads,
  `ArticlesSiteArea`.`id`,
  `ArticlesSiteArea`.`weight`
FROM
  `articles` AS `Article`
LEFT JOIN uploads AS `Upload` ON(
  `Article`.`id` = `Upload`.`foreign_key`
  AND 'Article' = `Upload`.`model`
)
LEFT JOIN site_areas AS `SiteArea` ON(`SiteArea`.`id` = '1')
LEFT JOIN site_areas_site_sections AS `SiteAreasSiteSection` ON(
  `SiteArea`.`id` = `SiteAreasSiteSection`.`site_area_id`
)
LEFT JOIN site_areas_site_sub_sections AS `SiteAreasSiteSubSection` ON(
  `SiteArea`.`id` = `SiteAreasSiteSubSection`.`site_area_id`
)
LEFT JOIN site_sections AS `SiteSection` ON(
  `SiteSection`.`id` = `SiteAreasSiteSection`.`site_section_id`
)
LEFT JOIN site_sub_sections AS `SiteSubSection` ON(
  `SiteSubSection`.`id` = `SiteAreasSiteSubSection`.`site_sub_section_id`
)
LEFT JOIN ranks_site_areas AS `RanksSiteArea` ON(
  `SiteArea`.`id` = `RanksSiteArea`.`site_area_id`
)
LEFT JOIN articles_site_sections AS `ArticlesSiteSection` ON(
  `SiteSection`.`id` = `ArticlesSiteSection`.`site_section_id`
)
LEFT JOIN articles_site_sub_sections AS `ArticlesSiteSubSection` ON(
  `SiteSubSection`.`id` = `ArticlesSiteSubSection`.`site_sub_section_id`
)
LEFT JOIN articles_site_areas AS `ArticlesSiteArea` ON(
  `ArticlesSiteArea`.`article_id` = `Article`.`id`
)
WHERE
  (
        (
              `ArticlesSiteArea`.`id` IS NOT NULL
        )
        OR(
              (
                    (`Upload`.`name` <> '')
                    AND(
                          (
                                (
                                      `Article`.`id` = `ArticlesSiteSection`.`article_id`
                                )
                                OR(
                                      `ArticlesSiteSection`.`article_id` IS NULL
                                )
                          )
                    )
                    AND(
                          (
                                (
                                      `Article`.`id` = `ArticlesSiteSubSection`.`article_id`
                                )
                                OR(
                                      `ArticlesSiteSubSection`.`article_id` IS NULL
                                )
                          )
                    )
                    AND(
                          (
                                (
                                      `RanksSiteArea`.`rank_id` = `Article`.`rank_id`
                                )
                                OR(
                                      `RanksSiteArea`.`rank_id` IS NULL
                                )
                          )
                    )
              )
        )
  )
GROUP BY
  `Article`.`id`
ORDER BY
  `ArticlesSiteArea`.`weight` DESC,
  `ArticlesSiteArea`.`id` DESC,
  SUBSTR(`Article`.`created`, 1, 10)DESC,
  FIELD(`Article`.`rank_id`, 1, 2, 3)DESC
LIMIT 4

最佳答案

我不太了解您的数据,但我怀疑您是否需要所有这些左联接。请记住,您可以使用括号来分隔逻辑。例如:

table1 t1
left join (
    table2 t2
    inner join table3 t3 on (t3.some_id = t2.some_id)
    inner join table4 t4 on (t4.some_id = t3.some_id)
) on (t1.some_id = t2.some_id)
left join table5 t5 on (t5.some_id = t1.some_id)

当您仅使用所需的连接类型时,查询可以执行得更好。

关于mysql - 加快编译的 MySQL 查询(目前大约需要 15 秒),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7000737/

相关文章:

MYSQL 日期复制和更新 + 14 天

php - 在 Controller 中使用模型函数

php - SQL/PHP : Joins with no matches on the other table (multiple tables)

javascript - 带 lodash/下划线的复合索引

mysql - 如何索引具有范围的表?

sql - mysql 动态变量

mysql - 获取与特定行组关联的行的行号

MySQL通过表连接获取数据

postgresql - 在 ZF2 中使用 tablegateway 连接 2 个表

javascript - 创建一个新的索引数组