优化这些MySQL查询的更好方法

时间:2012-07-01 04:52:30

标签: mysql query-optimization

我有两个MySQL表:

  • 属性(attributeid,name)
  • productsattributes(productid,attributeid,displayvalue)

对于名为“产品类型”的每个属性名称,必需的是获取与此“产品类型”关联的所有其他属性。作为示例 - 属性表将如下所示:

    attributeid  name
    1            A
    2            B
    3            Product Type
    4            D

productsattributes表格如下:

productid attributeid displayvalue
        1         3           FAN
        1         1           Brown
        1         2           Stand
        2         3           FAN
        2         4           D
        3         3           CAR
        3         4           imported

所以最终的结果应该是:

FAN (A,B, Product Type,D) 
CAR (Product Type, imported)

这是我的尝试:

  • 首先我从productattributes获取所有“displayvalues”:
SELECT DISTINCT displayvalue 
  FROM productsttributes 
 WHERE attributeid = 3;
  • 然后我遍历每个“displayvalues”以找到其他属性:
SELECT a.name 
 FROM attributes a 
 INNER JOIN productsattributes pa 
    ON pa.attributeid = a.attributeid AND productid in (
        SELECT productid 
        FROM productsttributes 
        WHERE dispalyvale =  '$displayvalue') 
 ORDER BY a.name;

问题是productattributes表有大约700万行,所以我的脚本需要永远...当然我不是在寻找10分钟的解决方案,但至少它会改善我的查询。

2 个答案:

答案 0 :(得分:1)

我将从以下陈述开始:

ALTER TABLE attributes ADD CONSTRAINT p_attributes PRIMARY KEY (attributeid);
ALTER TABLE productsattributes ADD CONSTRAINT p_productsattributes
    PRIMARY KEY(productid, attributeid);
ANALYZE TABLE attributes, productsattributes;

这将确保索引所有重要字段。

查询可能如下所示(也在SQL Fiddle上):

SELECT trg.displayvalue,
       group_concat(a.name ORDER BY trg.productid, a.attributeid)
  FROM (
        SELECT t.productid,t.displayvalue
          FROM attributes a
          JOIN productsattributes t USING (attributeid)
         WHERE a.name = 'Product Type') AS trg
  JOIN productsattributes p ON p.productid = trg.productid
  JOIN attributes a ON a.attributeid = p.attributeid
 GROUP BY trg.displayvalue
 ORDER BY 1;

请在您的问题中包含您的EXPLAIN输出和此查询。

答案 1 :(得分:0)

试试这个::

Select displayvalue, attribute_name
from 
(Select 
product_id from productsattributes pa inner join attributes_table at on (pa.attributeid=at.id) where at.name=?) as productList
inner join  productsattributes pa2 on(pa2.product_id=productList.product_id)
inner join attributes_table at2 on (pa2.attributeid=at2.id)