【问题标题】:MySQL exec time black magicMySQL exec 时间黑魔法
【发布时间】:2016-08-15 14:43:30
【问题描述】:

所以我的 mysql 查询每次都加载了 25 秒。我拆分查询,发现它可以在没有 WHERE 条件之一的情况下完美运行。导致问题的条件是:

eshop_products.id IN 
(SELECT product-id 
   FROM eshop_productCombinations 
   WHERE eshop_productCombinations.recomended = 1 
   GROUP BY product-id)

如果没有这个条件,查询需要 0.019 秒才能加载。但是当我单独执行这个选择时,加载只需要 0.026 秒:

SELECT product-id 
FROM eshop_productCombinations 
WHERE eshop_productCombinations.recomended = 1 
GROUP BY product-id

有人知道我的主要查询有什么问题吗?谢谢。

这是完整的查询(尽管我认为它对任何人都没有用):

SELECT
CAST(
  SUBSTRING_INDEX(
    GROUP_CONCAT(
      price_with_vat ORDER BY IF(eshop_products_cache.`stock` > 0, 1, 0) DESC,
      IF(
        eshop_products.`type_default_price`=2,eshop_products_cache.`price_with_vat`,
        if(
          eshop_products.`type_default_price`=0,eshop_products_cache.`default`,null
          )
      ) DESC,
      IF(eshop_products.`type_default_price`=1,eshop_products_cache.`price`, null) ASC
    ),
    ",
    ",
    1
  ) AS DECIMAL(10,2)
) AS `price_with_vat`,
SUBSTRING_INDEX(
  GROUP_CONCAT(
    eshop_products_cache.combination_id ORDER BY IF(eshop_products_cache.`stock` > 0, 1, 0) DESC,
    IF(
      eshop_products.`type_default_price`=2,
      eshop_products_cache.`price_with_vat`,
      if(
        eshop_products.`type_default_price`=0,
        eshop_products_cache.`default`,
        null
      )
    ) DESC,
    IF(eshop_products.`type_default_price`=1,eshop_products_cache.`price`, null)
    ASC
  ),
  ",
  ",
  1
) AS `combination_id`,
if( eshop_products.id in ('5993', '6144', '6663', '5120', '5376', '5632', '5888', '6400', '6656', '5121', '5377', '5633'), 1, 0) AS new
FROM `eshop_products` LEFT JOIN `eshop_products_cache` ON eshop_products_cache.product_id=eshop_products.`id` WHERE
(
  (
    (
      eshop_products.stockType = 2 AND eshop_products_cache.stock > 0
    )
    OR eshop_products.stockType <> 2
  )
)
AND
(
  price_with_vat > 0
)
AND
(
  eshop_products.recomended = 1
  OR
  eshop_products.id IN (
    SELECT `product-id` FROM eshop_productCombinations WHERE eshop_productCombinations.recomended = 1 GROUP BY `product-id`
  )
)
AND
(
  eshop_products.active = '1'
)
AND (dateStartPublish <= NOW() OR dateStartPublish IS NULL)
AND (dateStopPublish >= NOW() OR dateStopPublish IS NULL)
GROUP BY `eshop_products`.`id`, `eshop_products_cache`.`product_id` ORDER BY RAND() ASC LIMIT 5

【问题讨论】:

  • 不想听起来讽刺,但这是这部分eshop_products.id IN (SELECT product-id FROM eshop_productCombinations WHERE eshop_productCombinations.recomended = 1 GROUP BY product-id)
  • 您是否想问如何加快速度?然后发布您的解释输出并提供有关您的表的一些信息,最好是 show create table。
  • 我想我真的很笨,我不明白问题出在哪里
  • 但你刚刚说没有它也能完美运行1
  • 嗯,是的,它通常在其他网站上执行 1-3 秒,但这次由于某些原因需要 20+ 秒

标签: mysql select join where


【解决方案1】:

Anthony 建议,子查询必须替换为以下代码:

  EXISTS (
  SELECT 1 FROM eshop_productCombinations 
  WHERE eshop_productCombinations.recomended = 1
  AND product-id = eshop_products.id )

【讨论】:

  • 仅供参考,如果可能,较新版本的 MySQL 将尝试自动将 IN 子句转换为 EXISTS 子句,但这并不总是服务器可以轻松安全地应用的简单转换,这这就是为什么最好理解为什么某些 SQL 查询设计更费力,并在考虑到这种理解的情况下设计查询。
  • 而且,我不确定 group by 是您在该子查询中想要的。您没有任何需要它们的聚合函数,并且 EXISTS 函数可能不会像您认为的那样使子查询结果不同。
  • 知道了,另外,这只是旧 CMS 的一部分(它基于旧技术,并且迫切需要在不久的将来重建)所以这肯定会在不久的将来派上用场。谢谢。
  • 但是,是的,你在正确的轨道上。很高兴我能指出你正确的方向
猜你喜欢
  • 2014-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 2016-12-05
  • 2020-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多