【问题标题】:slow query with lots of left joins具有大量左连接的慢查询
【发布时间】:2018-01-13 04:55:20
【问题描述】:

当我在数据库中检查 SHOW PROCESSLIST; 时,我得到了以下查询。它大量使用 CPU(超过 100%),完成查询需要 80 秒。我们有一个单独的数据库服务器(64GB RAM)。

INSERT INTO `search_tmp_598075de5c7e67_73335919` 
SELECT `main_select`.`entity_id`, MAX(score) AS `relevance` 
  FROM (SELECT `search_index`.`entity_id`, (((0)) * 1) AS score  
        FROM `catalogsearch_fulltext_scope1` AS `search_index`
        LEFT JOIN `catalog_eav_attribute` AS `cea`
                    ON search_index.attribute_id = cea.attribute_id
        LEFT JOIN `catalog_category_product_index` AS `category_ids_index` 
                    ON search_index.entity_id = category_ids_index.product_id
        LEFT JOIN `review_entity_summary` AS `rating`
                    ON `rating`.`entity_pk_value`=`search_index`.entity_id
                   AND `rating`.entity_type = 1
                   AND `rating`.store_id  =  1
       WHERE (category_ids_index.category_id = 2299)
  ) AS `main_select`
 GROUP BY `entity_id`
 ORDER BY `relevance` DESC
 LIMIT 10000

为什么这个查询会占用我全部的 CPU 资源?

【问题讨论】:

  • 在 SELECT 部分中出现错误或没有索引,也许我们需要查看 select 部分的说明。
  • 你的表的主键是什么?
  • 这是一个查询不应该是什么样子的示例。
  • 请阅读meta.stackoverflow.com/a/271056,尤其是关于查询性能的部分。那么请edit你的问题。
  • 此查询不是我们创建的,这是用于索引的默认 Magento 查询。有没有什么mysql配置设置可以解决这个问题?

标签: mysql magento mariadb query-performance


【解决方案1】:

一些低效率:

  • 外部联接catalog_category_product_index 的记录存在非空条件。这会将外部连接变为内部连接。使用inner join 子句会更有效。

  • 不需要嵌套查询:可以直接在内部查询上进行分组、排序和限制。

  • (((0)) * 1) 只是表示0 的一种复杂方式,并且采用其中的MAX 显然仍会为所有记录返回0 的相关性。这不仅是输出0 的低效方式,而且毫无意义。我假设您的真实查询在那里有一些不太明显的计算,这可能需要优化。

  • 如果catalog_eav_attribute.attribute_id 是一个唯一字段,则外部连接该表没有任何意义,因为该数据不会在任何地方使用

  • 如果review_entity_summary.entity_pk_value 是唯一的(至少在entity_type = 1store_id = 1 时),那么外部连接该表也没有用处,因为该数据不会在任何地方使用

    李> 1234563不需要),那么也不需要外连接。

有了这些假设,select 部分可以简化为:

SELECT      search_index.entity_id, 
            MAX(((0)) * 1) AS relevance 
FROM        catalogsearch_fulltext_scope1 AS search_index 
INNER JOIN  catalog_category_product_index AS category_ids_index 
        ON  search_index.entity_id = category_ids_index.product_id 
WHERE       category_ids_index.category_id = 2299
GROUP BY    search_index.entity_id 
ORDER BY    relevance DESC 
LIMIT       10000

我还是把(((0)) * 1)留在了那里,但这真的没有意义。

【讨论】:

    猜你喜欢
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多