Ускорение скомпилированного запроса MySQL (в настоящее время занимает около 15 секунд) - PullRequest
1 голос
/ 09 августа 2011

Я новичок в области индексирования и не до конца понимаю все, но - у меня есть все таблицы, использующие индекс, кроме основной - таблицы «статей» («Статья»).У меня не так много записей, но запрос занимает около 15 секунд (очевидно, это неприемлемо).

Я использую 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

1 Ответ

0 голосов
/ 10 августа 2011

Я мало что знаю о ваших данных, но сомневаюсь, что вам нужны все эти левые соединения .Имейте в виду, что вы можете использовать скобки для разделения логики.Например:

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)

Запрос может работать лучше, если вы используете только необходимые типы объединения.

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