1

我在进行良好的 MySQL 查询方面非常糟糕。我创建了这个:

SELECT SQL_CALC_FOUND_ROWS
  `products_stock`.`products_id`,
  `products_stock`.`products_stock_attributes`,
  `products_stock`.`products_stock_quantity`,
  `products`.`manufacturers_id`,
  `products_description`.`products_name`
FROM `products_stock` 
  LEFT JOIN  `products`
    ON  `products_stock`.`products_id` = `products`.`products_id` 
  LEFT JOIN  `products_description`
    ON  `products_stock`.`products_id` = `products_description`.`products_id` 
  LEFT JOIN  `products_to_categories`
    ON `products_stock`.`products_id` = `products_to_categories`.`products_id` 
WHERE `products_stock`.`products_stock_quantity` >=3
  AND `products`.`products_status` = 1
  AND ISNULL(`products`.`products_image`) = false
  AND `products`.`products_image` != ""
  AND EXISTS(
   select * from `allegro`
   where `products_stock`.`products_id` = `allegro`.`product_id` 
     and `allegro`.`attributes` =  `products_stock`.`products_stock_attributes`
  ) = false

products表有大约 17k 行, allegro表有大约 3k 行。

查询Idea是选择所有产品,其中stock_quanity > 3,哪里是照片,哪里是allegro表中没有产品id。

现在查询大约需要 10 秒。我不知道如何优化它。

@解决了

我已经为 allegro.product_id 和 allegro.attributes 添加了索引,现在查询时间不到半秒。谢谢大家的帮助

4

2 回答 2

2

摆脱这些EXISTS ( SELECT … ) = FALSE东西。

把它变成这样的东西:

LEFT JOIN allegro
          ON products_stock.products_id = allegro.product_id
         AND allegro.attributes = products_stock.products_stock_attributes
…
WHERE allegro.product_id IS NULL

请参阅 MySQL 文档中的Rewriting Subqueries as Joins章节。

进一步的建议:

  • 不要加入你不使用的表,比如products_to_categories
  • 而不是ISNULL(…) = FALSE… IS NOT NULL
于 2012-07-11T09:20:33.087 回答
0

在尝试以下方法之前,请检查您的表引擎设置为 innoDB 并正确索引,然后您可以尝试直接加入。它将首先强制查看左表。

另一种方法是使用memcache进行慢速查询。使用该方法可以将查询结果缓存到数组中,避免频繁查询db。缓存的结果可以在指定的时间段后更新。

于 2012-07-11T09:36:07.580 回答