通过添加一个查询过滤器来查询我的性能低下。
以下是完整查询:
SELECT
`c`.`categories_id`,
`c`.`section_id`,
`c`.`categories_status`,
IF(`c`.`categories_status` = 1, 'ON', 'OFF') AS `categories_status_name`,
TRIM(`cd`.`categories_name`) AS `categories_name`,
IF(`cd`.`concert_date` <> '',
DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%d.%m.%Y'),
NULL
) AS `concert_date`,
TRIM(`cd`.`concert_time`) AS `concert_time`
FROM
`categories` `c`
JOIN `categories_description` `cd` ON `c`.`categories_id` = `cd`.`categories_id`
WHERE
`c`.`plan_id` > 2
AND
`c`.`categories_status` = '1'
AND
`cd`.`categories_id` NOT IN(
SELECT
`p`.`parent_id`
FROM
`products` `p`
WHERE
`p`.`product_type` = 'X'
AND
`p`.`parent_id` = `cd`.`categories_id`
GROUP BY `p`.`product_type`
)
GROUP BY `c`.`categories_id`
ORDER BY DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%Y-%m-%d') DESC, `cd`.`categories_name` DESC
在这个查询中,我有一个新的过滤器,添加的内容如下所示:
`cd`.`categories_id` NOT IN(
SELECT
`p`.`parent_id`
FROM
`products` `p`
WHERE
`p`.`product_type` = 'X'
AND
`p`.`parent_id` = `cd`.`categories_id`
GROUP BY `p`.`product_type`
)
我还尝试使用NOT EXISTS
再做一个解决方案,但这更糟糕了:
NOT EXISTS (
SELECT
DISTINCT 1
FROM
`products` `p`
WHERE
`p`.`product_type` = 'X'
AND
`p`.`parent_id` = `cd`.`categories_id`
GROUP BY `p`.`product_type`
)
我的主要问题是,在我添加此过滤器以删除包含X
产品的类别后,性能开始变得非常糟糕。如果没有此过滤器页面,则加载时间为0.5-0.8秒,但此过滤器页面加载时间为8到10秒。
有人可以帮我优化此查询吗?
答案 0 :(得分:1)
这可行。大多数引擎在NOT IN / NOT EXISTS中都不是很好,除非它们在内部将查询修改为下面的表单。 至少值得一试。
SELECT
`c`.`categories_id`,
`c`.`section_id`,
`c`.`categories_status`,
IF(`c`.`categories_status` = 1, 'ON', 'OFF') AS `categories_status_name`,
TRIM(`cd`.`categories_name`) AS `categories_name`,
IF(`cd`.`concert_date` <> '',
DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%d.%m.%Y'),
NULL
) AS `concert_date`,
TRIM(`cd`.`concert_time`) AS `concert_time`
FROM
`categories` `c` JOIN `categories_description` `cd`
ON `c`.`categories_id` = `cd`.`categories_id`
LEFT JOIN `products` `p`
ON `p`.`parent_id` = `cd`.`categories_id`
AND `p`.`product_type` = 'X'
WHERE
`c`.`plan_id` > 2
AND
`c`.`categories_status` = '1'
AND
`p`.`parent_id` IS NULL
GROUP BY `c`.`categories_id`
ORDER BY DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%Y-%m-%d') DESC, `cd`.`categories_name` DESC
答案 1 :(得分:0)
这是我得到的最快的解决方案。
SELECT
`c`.`categories_id`,
`c`.`section_id`,
`c`.`categories_status`,
IF(`c`.`categories_status` = 1, 'ON', 'OFF') AS `categories_status_name`,
TRIM(`cd`.`categories_name`) AS `categories_name`,
IF(`cd`.`concert_date` <> '',
DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%d.%m.%Y'),
NULL
) AS `concert_date`,
TRIM(`cd`.`concert_time`) AS `concert_time`
FROM
`categories` `c`
INNER JOIN `categories_description` `cd` ON `c`.`categories_id` = `cd`.`categories_id`
LEFT JOIN `products` `p` ON `p`.`parent_id` = `cd`.`categories_id`
WHERE
`c`.`plan_id` > 2
AND
`c`.`categories_status` = '1'
AND `p`.`product_type` != 'X'
GROUP BY `c`.`categories_id`
ORDER BY DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%Y-%m-%d') DESC, `cd`.`categories_name` DESC
感谢@NigelRen,他让我知道如何解决这个问题。 @Ronald给出了几乎相同的解决方案,但比我的解决方案慢了一点(0.400秒)。
谢谢你们的帮助!