我有一个我想要优化的SQL查询的地狱。让我们来谈谈它

时间:2011-12-27 02:15:58

标签: mysql sql database indexing

所以,这是一个问题,可能会让SQL专家跳过我,叫我懒惰,但我很难过。我们的网上商店今天早上崩溃和烧毁,这是可疑的查询。我整天都在考虑这个问题,并没有想出任何天才的优化。我可以得到一些帮助吗?任何关键指标?重组的方法是什么?我意识到这就像问墙的另一边是什么,然后给你一个望远镜指向另一个方向,但认为它值得一试:

SELECT DISTINCT (SELECT filename FROM (SELECT DISTINCT y.value AS label, x.value AS filename 
                        FROM   `catalog_product_super_link` AS z 
                        INNER JOIN `catalog_product_entity_varchar` AS y 
                        ON z.product_id = y.entity_id 
                        INNER JOIN `catalog_product_entity_varchar` AS x 
                        ON z.product_id = x.entity_id 
                        WHERE  parent_id = (SELECT entity_id 
                                             FROM   `catalog_product_entity`
                                             WHERE  sku LIKE 'F11-ARC-7710%' 
                                             LIMIT  0, 1) 
                        AND y.attribute_id = (SELECT attribute_id 
                                               FROM   `eav_attribute` 
                                               WHERE  attribute_code = 'image_label' 
                                               AND entity_type_id = (SELECT entity_type_id FROM `eav_entity_type` WHERE entity_type_code = 'catalog_product') LIMIT 0, 1) 
                        AND x.attribute_id = (SELECT attribute_id 
                                               FROM   `eav_attribute` 
                                               WHERE  attribute_code = 'image' 
                                               AND entity_type_id = (SELECT entity_type_id FROM `eav_entity_type` WHERE entity_type_code = 'catalog_product'))) AS images WHERE c.value LIKE CONCAT(label,'%') LIMIT 0, 1) AS image,
                        pricing_value, 
                        is_percent, 
                        value_index, 
                        c.value AS label,
                        d.sort_order AS sort_order
                        FROM   `catalog_product_super_attribute_pricing` AS a 
                        INNER JOIN `catalog_product_super_attribute_label` AS b 
                        ON a.product_super_attribute_id = b.product_super_attribute_id 
                        INNER JOIN `eav_attribute_option_value` AS c 
                        ON value_index = c.option_id 
                        INNER JOIN `eav_attribute_option` AS d
                        ON c.option_id = d.option_id 
                        WHERE  a.product_super_attribute_id = (SELECT product_super_attribute_id 
                                                               FROM   `catalog_product_super_attribute` 
                                                               WHERE  product_id = 5928 
                                                               AND attribute_id = 143 LIMIT 0, 1) 

                        UNION ALL

                        SELECT DISTINCT (SELECT filename FROM (SELECT DISTINCT y.value AS label, x.value AS filename 
                                         FROM   `catalog_product_super_link` AS z 
                                         INNER JOIN `catalog_product_entity_varchar` AS y 
                                         ON z.product_id = y.entity_id 
                                         INNER JOIN `catalog_product_entity_varchar` AS x 
                                         ON z.product_id = x.entity_id 
                                         WHERE  parent_id = (SELECT entity_id 
                                                             FROM   `catalog_product_entity`
                                                             WHERE  sku LIKE 'F11-ARC-7710%' 
                                                             LIMIT  0, 1) 
                                         AND y.attribute_id = (SELECT attribute_id 
                                                               FROM   `eav_attribute`
                                                               WHERE  attribute_code = 'image_label' 
                                                               AND entity_type_id = (SELECT entity_type_id FROM `eav_entity_type` WHERE entity_type_code = 'catalog_product') LIMIT 0, 1) 
                                         AND x.attribute_id = (SELECT attribute_id 
                                                               FROM   `eav_attribute` 
                                                               WHERE  attribute_code = 'image' 
                                                               AND entity_type_id = (SELECT entity_type_id FROM `eav_entity_type` WHERE entity_type_code = 'catalog_product'))) AS images
                                                               WHERE label LIKE CONCAT((SELECT value FROM `eav_attribute_option_value` WHERE option_id = c.value LIMIT 0, 1),'%') LIMIT 0, 1) AS image,
                                        0 AS pricing_value, 
                                        0 AS is_percent, 
                                        c.value AS value_index, 
                                        (SELECT value FROM `eav_attribute_option_value` WHERE  option_id = c.value LIMIT  0, 1) AS label,
                                        (SELECT sort_order FROM `eav_attribute_option` WHERE option_id = c.value LIMIT 0, 1) AS sort_order
                        FROM   `catalog_product_entity` AS a 
                        INNER JOIN `cataloginventory_stock_status` AS b 
                        ON a.entity_id = b.product_id 
                        INNER JOIN `catalog_product_entity_int` AS c 
                        ON a.entity_id = c.entity_id 
                        INNER JOIN `cataloginventory_stock_item` AS d 
                        ON a.entity_id = d.product_id 
                        WHERE  c.attribute_id = (SELECT attribute_id 
                                                 FROM   `eav_attribute` 
                                                 WHERE  attribute_code = 'choose_size' 
                                                 AND entity_type_id = (SELECT entity_type_id FROM `eav_entity_type` WHERE entity_type_code = 'catalog_product') LIMIT 0, 1) 
                        AND a.entity_id IN (SELECT DISTINCT product_id 
                                            FROM   `catalog_product_super_link` 
                                            WHERE  parent_id = (SELECT entity_id FROM `catalog_product_entity` WHERE sku LIKE 'F11-ARC-7710%' LIMIT  0, 1)) 
                        AND (b.qty > 0 OR d.manage_stock = 0) 
                        AND (SELECT value 
                             FROM   `eav_attribute_option_value` 
                             WHERE  option_id = c.value 
                             LIMIT  0, 1) NOT IN (SELECT c.value 
                                                  FROM `catalog_product_super_attribute_pricing` AS a
                                                  INNER JOIN `catalog_product_super_attribute_label` AS b ON a.product_super_attribute_id = b.product_super_attribute_id 
                                                  INNER JOIN `eav_attribute_option_value` AS c ON value_index = c.option_id 
                                                  WHERE  a.product_super_attribute_id = (SELECT product_super_attribute_id FROM `catalog_product_super_attribute`
                                                                                 WHERE product_id = 5928 
                                                                                         AND attribute_id = 143))
                        ORDER BY sort_order

提前致谢!

4 个答案:

答案 0 :(得分:6)

如果没有更多信息,甚至是你的试验床,那将是非常不可能的......

但是除了运行解释计划并按照其他人的建议添加索引之外 - 我看到一些可能可以从中抽出的东西来改进:

例如,你有重复的子选择:像这样:

(SELECT entity_id 
FROM   `catalog_product_entity`
WHERE  sku LIKE 'F11-ARC-7710%' 
LIMIT  0, 1) 

考虑将这些提取到FROM子句的最高级别,然后加入以获得结果。一次不是很多次。如果您对3或4个变体执行此操作,您应该看到改进。

另一件看起来不太正确的事情是DISTINCT在子选择中非常深入地嵌套......你可能不需要那些它们可能会增加开销。

答案 1 :(得分:3)

哦,我的。

除了WHERE子句和EXPLAIN PLAN中每一列的索引,我都没有提供任何东西,以查看是否有TABLE SCAN。

我的经验法则是七个JOINS或更多将表现不佳。我的INNER JOIN条款比你的更多。我对此查询有严重的保留意见。是否可能反规范化? VIEW怎么样?这可以帮到你吗?你比我更了解你的架构和问题。

答案 2 :(得分:3)

快速回应。

你可以在PLSQL的等值环境中做到吗? 你能消除那些子查询吗?

先做它们并存储结果。 假设他们返回一行。

然后,写一个传入变量的较小查询。

答案 3 :(得分:1)

我前几天回答的这个问题可能对你有所帮助:

How can I optimize this SQL query with nested SELECT's?

这是为了提高嵌套查询的效率。我怀疑如果你单独处理你的嵌套选择,然后使用结果形成一个更简单的查询,它会有所帮助。授予游览查询要复杂得多,所以可能还有更多,但希望这是一个开始。