2011-12-27 37 views
3

所以,這裏有一個問題,可能會讓SQL專家們跳過我,稱我爲懶惰,但我很難過。我們的網上商店今天早上墜毀並燒燬,這裏是可疑的查詢。我一整天都在想這件事,而且還沒有拿出任何天才的優化。我可以得到一些幫助嗎?任何關鍵指標?如何重組這個?我意識到這好像叫什麼在牆的另一邊,然後給你一個望遠鏡指向另一個方向,但想通這是值得一試:我有一個我想優化的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 

提前感謝!

+2

該查詢過於冗長而且花費時間理解,因此可以進行優化。你能給出一個(小的!)樣本的輸入數據,表格結構和所需的輸出嗎? – Bojangles 2011-12-27 02:26:12

回答

3

快速響應。

你可以在PLSQL的equivilent中做到這一點嗎? 你可以消除這些子查詢嗎?

先執行並存儲結果。 假設它們返回一行。

然後,寫一個較小的查詢傳遞變量。

+0

PLSQL是Oracle特有的。標籤說MySQL。但是存儲的proc想法是一個好主意。 – duffymo 2011-12-27 02:30:01

+0

這不是一個壞主意。所有這些子查詢對於通過我們的各種開發/分期/實時環境(我們使用Magento以及Magento上的任何人都會理解 - ID的變化)都可以使這個特定的查詢成爲必需。但是打破它們只會把它變成7個查詢,而不是一個...... – drewgillson 2011-12-27 06:34:53

+0

在這種情況下,我相信7個查詢會比一個嵌套更快。它也應該能夠檢測你的哪個環境並有條件地構建正確的查詢。 – Ravenex 2011-12-27 07:46:07

3

哦,我的。

除了WHERE子句和EXPLAIN PLAN中每列的索引,我沒有什麼可以提供的,以查看是否有TABLE SCAN。

我的經驗法則是七個連接或更多將表現不佳。我計算更多的INNER JOIN子句比你的更多。我會對這個查詢有嚴重的保留。是否有可能反規範化? VIEW怎麼樣?可以幫助你嗎?你比我更瞭解你的模式和問題。

1

這個問題我回答有一天可能會幫助您了一點:

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

這是關於進行嵌套查詢更高效。我會懷疑,如果你分別處理你的嵌套選擇,然後使用結果形成一個更簡單的查詢,這將有所幫助。授予的巡視查詢要複雜得多,所以可能會有更多,但希望這是一個開始。

6

這將是幾乎不可能沒有更多的一些信息,甚至您的測試臺...

但除了運行解釋計劃,並添加索引他人的建議 - 我看到了一些東西,或許可以拉出的有改善的事情:

比如你有反覆子查詢:像這樣的:

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

考慮拉這些走出來的最高水平FROM子句中,然後加入到得到結果。一次沒多少次。如果你爲3或4個變體做這個,你應該看到改進。

另一件看起來不太正確的事情是DISTINCT在子查詢中嵌套得很深......你可能不需要這些,它們可能會增加開銷。