即使使用 INNER JOIN 而不是 IN,MySQL 查询也非常慢

Posted

技术标签:

【中文标题】即使使用 INNER JOIN 而不是 IN,MySQL 查询也非常慢【英文标题】:MySQL queries are very slow even using INNER JOIN instead of IN 【发布时间】:2014-01-21 22:52:45 【问题描述】:

我有三个表:product(10k 条记录)、product_attribute(4k 条记录)和 product_value(2m 条记录)。 product 和 product_attribute 通过 product_value 连接。 我想检索特定产品(例如 product_id = 001)及其各自的属性名称和属性值。一开始我试试

SELECT product.product_id, product_attribute.attribute_name, product_value.attribute_value

FROM product, product_attribute, product_value

WHERE product.product_id = 001 AND product.product_id = product_value.product_id AND product_attribute.product_attribute_id IN (SELECT product_value.product_attribute_id FROM product_value WHERE product_value.product_id = 001)

但它非常慢。然后我用INNER JOIN代替IN

SELECT product.product_id, product_attribute.attribute_name,  product_value.attribute_value FROM product

INNER JOIN product_value ON product.product_id = 001 AND product.product_id = product_value.product_id

INNER JOIN product_attribute ON product_attribute.product_attribute_id = product_value.product_attribute_id WHERE product.product_id = 001

但还是很慢:查询在 36 分钟内返回 31 行!

有没有更好的办法解决这个问题?

解释查询给出:

*************************** 1. row ***********
           id: 1
  select_type: SIMPLE
        table: product_attribute
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 5247
        Extra:
*************************** 2. row ***********
           id: 1
  select_type: SIMPLE
        table: product
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 91818
        Extra: Using where; Using join buffer
*************************** 3. row ***********
           id: 1
  select_type: SIMPLE
        table: product_value
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1731016
        Extra: Using where; Using join buffer

【问题讨论】:

你想从这个查询中得到什么信息? 解释您的查询和更新 你的表有索引吗? 【参考方案1】:

试试这个:

SELECT p.product_id, pa.attribute_name, pv.attribute_value 
FROM product p 
INNER JOIN product_value pv ON p.product_id = pv.product_id
INNER JOIN product_attribute pa ON pa.product_attribute_id = pv.product_attribute_id 
WHERE p.product_id = 001

运行此查询,如果您仍然面临查询比添加您EXPLAIN 上述查询的计划慢

您必须在列上创建索引以提高性能。

    product_value 表的product_id 列上创建索引

    product_value 表的product_attribute_id 列上创建索引

【讨论】:

它没有帮助...我已经发布了EXPLAIN。查询似乎完全扫描了表,这是有线的。 @user3138073 检查我更新的答案。创建索引后检查查询性能。如果您仍然发现性能比再次慢,请检查您的查询的EXPLAIN 计划并在您的问题中更新 @user3138073 请为这三个表更新您的create table 脚本

以上是关于即使使用 INNER JOIN 而不是 IN,MySQL 查询也非常慢的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server-聚焦INNER JOIN AND IN性能分析(十四)

SQL Server-聚焦INNER JOIN AND IN性能分析(十四)

我啥时候应该使用 CROSS APPLY 而不是 INNER JOIN?

对于 SQL,啥时候开始需要始终使用“Inner Join”而不是隐式连接?

Oracle中Inner join和Where的区别

(My)SQL 如何评估链式 LEFT/INNER JOIN?