Оптимизация запросов с несколькими объединениями сквозных таблиц - PullRequest
0 голосов
/ 28 апреля 2011

Мне нужно иметь отдельные записи для всех, сейчас, так как большинство продуктов имеют несколько ключевых слов, поэтому записываются несколько записей.Это запрос MySQL, и его нужно оптимизировать для поиска, потому что он довольно медленный.Какие-нибудь мысли?Я ценю помощь

SELECT DISTINCT 
  `p`.`slug`,
  `p`.`image_code`,
  `p`.`name` AS `products_name`,
  `a`.`name` AS `authors_name`,
  `c`.`name` AS `category_name`,
  `cf`.`name` AS `color_family_name` 
FROM
  `products` AS `p` 
  INNER JOIN
  `categories_products` AS `cp` 
  ON (`p`.`id` = `cp`.`product_id`) 
  INNER JOIN
  `categories` AS `c` 
  ON (`cp`.`categories_id` = `c`.`id`) 
  INNER JOIN
  `artists_products` AS `ap` 
  ON (`p`.`id` = `ap`.`product_id`) 
  INNER JOIN
  `artists` AS `a` 
  ON (`ap`.`artists_id` = `a`.`id`) 
  INNER JOIN
  `products_keywords` AS `pk` 
  ON (`p`.`id` = `pk`.`product_id`) 
  INNER JOIN
  `keywords` AS `kw` 
  ON (`pk`.`keyword_id` = `kw`.`id`) 
  INNER JOIN
  `colors_products` AS `cop` 
  ON (`p`.`id` = `cop`.`product_id`) 
  INNER JOIN
  `colors` AS `col` 
  ON (`cop`.`colors_id` = `col`.`id`) 
  INNER JOIN
  `colors_family` AS `cf` 
  ON (
    `col`.`color_family_id` = `cf`.`id`
  ) 
WHERE `p`.`image_code` LIKE '%red%' 
  OR `p`.`slug` LIKE '%red%' 
  OR `p`.`name` LIKE '%red%' 
  OR `a`.`name` LIKE '%red%' 
  OR `c`.`name` LIKE '%red%' 
  OR `kw`.`name` LIKE '%red%' 
  OR `col`.`name` LIKE '%red%' 
  OR `cf`.`name` LIKE '%red%' 
  OR `col`.`pantone_code` LIKE '%red%' 
  AND `p`.`active` = 1 
LIMIT 60 

1 Ответ

2 голосов
/ 28 апреля 2011

К сожалению, поскольку вы используете в запросе большое количество критериев ИЛИ, производительность будет очень хорошей.Основной областью оптимизации будет ограничение наборов результатов перед объединением и перемещение ненужных объединений в предложение WHERE.Это позволит MySQL оптимизировать данные, которые он использует, чтобы ускорить запрос.Поскольку вы не возвращаете данные из таблицы ключевых слов, это логичное место для начала.Кроме того, вы можете сократить таблицу продуктов заранее, чтобы отменить неактивные записи.

SELECT DISTINCT 
  `p`.`slug`,
  `p`.`image_code`,
  `p`.`name` AS `products_name`,
  `a`.`name` AS `authors_name`,
  `c`.`name` AS `category_name`,
  `cf`.`name` AS `color_family_name` 
FROM
  (SELECT `p`.`id`, `p`.`slug`, `p`.`image_code`, `p`.`name` FROM `products` AS `p` WHERE `p`.`active` = 1) AS `p`
INNER JOIN `artists_products` AS `ap` ON (`p`.`id` = `ap`.`product_id`) 
INNER JOIN `artists` AS `a` ON (`ap`.`artists_id` = `a`.`id`) 

INNER JOIN `categories_products` AS `cp` ON (`p`.`id` = `cp`.`product_id`) 
INNER JOIN `categories` AS `c` ON (`cp`.`categories_id` = `c`.`id`) 

INNER JOIN `colors_products` AS `cop` ON (`p`.`id` = `cop`.`product_id`) 
INNER JOIN `colors` AS `col` ON (`cop`.`colors_id` = `col`.`id`) 
INNER JOIN `colors_family` AS `cf` ON (`col`.`color_family_id` = `cf`.`id`) 

WHERE `p`.`image_code` LIKE '%red%' 
  OR `p`.`slug` LIKE '%red%' 
  OR `p`.`name` LIKE '%red%' 
  OR `a`.`name` LIKE '%red%' 
  OR `c`.`name` LIKE '%red%' 
  OR `p`.`id`. IN (SELECT `pk`.`product_id` FROM `products_keywords` INNER JOIN `keywords` AS `kw` ON (`pk`.`keyword_id` = `kw`.`id`) WHERE `kw`.`name` LIKE '%red%')
  OR `col`.`name` LIKE '%red%' 
  OR `cf`.`name` LIKE '%red%' 
  OR `col`.`pantone_code` LIKE '%red%'
LIMIT 60 
...