2012-11-16 117 views
0

我有一個MySQL的大查詢magento這要花很多時間。我試圖優化它,但是我的MySQL知識還不足以讓它解決,所以也許有人可以看一看,並給我一些正確方向的提示。OR在MySQL哪裏使查詢非常緩慢

Select Distinct 
    `e`.*, 
    `cat_index`.`position` AS `cat_index_position`, 
    `price_index`.`price`, 
    `price_index`.`tax_class_id`, 
    `price_index`.`final_price`, 
    IF(price_index.tier_price IS NOT NULL, 
     LEAST(price_index.min_price, price_index.tier_price), 
     price_index.min_price) AS `minimal_price`, 
    `price_index`.`min_price`, 
    `price_index`.`max_price`, 
    `price_index`.`tier_price` 
From 
    `catalog_product_entity` AS `e` 
    Inner Join 
    `catalog_category_product_index` As `cat_index` 
    On cat_index.product_id=e.entity_id And 
     cat_index.store_id=1 And 
     cat_index.visibility In(2, 4) And 
     cat_index.category_id='2' 
    Inner Join 
    `catalog_product_index_price` AS `price_index` 
    On price_index.entity_id = e.entity_id And 
     price_index.website_id = '1' And 
     price_index.customer_group_id = 0 
    Left Join 
    `beta_entity_product` AS `beta` 
    On e.entity_id = beta.product_id And 
     beta.entity_id In (81558, 81559, ... stupidly long list of ids) 
    Left Join 
    `catalog_product_entity_int` AS `is_uni` 
    On e.entity_id = is_uni.entity_id And 
     attribute_id = 179 
Where 
is_uni.value = 1 OR 
beta.product_id IS NOT NULL 

如果我只是在WHERE子句中的一切條件1是好的,但與OR需要有時一些時間才能完成並且那太長了。我必須獲得哪些選項才能獲得更好的結果?另一個問題是,我無法從中進行更多的查詢,只是將結果加在一起。一切都必須在1個查詢中。

當我做一個對查詢我得到以下結果EXPLAIN(JSON格式複製爲更好的概述):

{ 
     "data": 
     [ 
      { 
       "id": 1, 
       "select_type": "SIMPLE", 
       "table": "e", 
       "type": "ALL", 
       "possible_keys": "PRIMARY", 
       "key": null, 
       "key_len": null, 
       "ref": null, 
       "rows": 213396, 
       "Extra": "Using temporary" 
      }, 
      { 
       "id": 1, 
       "select_type": "SIMPLE", 
       "table": "beta", 
       "type": "range", 
       "possible_keys": "PRIMARY", 
       "key": "PRIMARY", 
       "key_len": "4", 
       "ref": null, 
       "rows": 2833, 
       "Extra": "Using where; Using index" 
      }, 
      { 
       "id": 1, 
       "select_type": "SIMPLE", 
       "table": "is_uni", 
       "type": "ref", 
       "possible_keys": "UNQ_CATALOG_PRODUCT_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID,IDX_CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID,IDX_CATALOG_PRODUCT_ENTITY_INT_ENTITY_ID", 
       "key": "UNQ_CATALOG_PRODUCT_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID", 
       "key_len": "6", 
       "ref": "unc_cpk.e.entity_id,const", 
       "rows": 1, 
       "Extra": "Using where" 
      }, 
      { 
       "id": 1, 
       "select_type": "SIMPLE", 
       "table": "cat_index", 
       "type": "eq_ref", 
       "possible_keys": "PRIMARY,IDX_CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY,15D3C269665C74C2219037D534F4B0DC", 
       "key": "PRIMARY", 
       "key_len": "10", 
       "ref": "const,unc_cpk.e.entity_id,const", 
       "rows": 1, 
       "Extra": "Using where" 
      }, 
      { 
       "id": 1, 
       "select_type": "SIMPLE", 
       "table": "price_index", 
       "type": "eq_ref", 
       "possible_keys": "PRIMARY,IDX_CATALOG_PRODUCT_INDEX_PRICE_CUSTOMER_GROUP_ID,IDX_CATALOG_PRODUCT_INDEX_PRICE_WEBSITE_ID", 
       "key": "PRIMARY", 
       "key_len": "8", 
       "ref": "unc_cpk.cat_index.product_id,const,const", 
       "rows": 1, 
       "Extra": "Using where" 
      } 
     ] 
    } 
+0

這個查詢中究竟是這個'或'。它是...「寬」。 –

+0

在最後的查詢結束位置:WHERE is_uni.value = 1 OR beta.product_id IS NOT NULL – n3on

+0

可以顯示describe table'catalog_product_entity'的輸出和EXPLAIN w/o的輸出嗎? –

回答

1

有多種解決方案:

1)分裂的查詢和使用UNION - 可能的排序和分頁問題 2)添加將只用於此過濾器,而不是

is_uni的新屬性。值= 1或測試版。PRODUCT_ID IS NOT NULL

你會被查詢只

feature_filter = 1

3)分解查詢到多個查詢 - 我建議這是因爲查詢的第一大步,因爲這一個真的很棒在腳下拍攝自己的方式

順便說一句。使用不同的查詢與很多列吃了很多資源(mysql需要比較每列值!)

1

如果有一個條件每個查詢都單獨快,嘗試做

Select 
    blah 
Where 
    is_uni.value = 1 
Union 
Select 
    blah 
Where 
    beta.product_id Is Not Null 

只要他們不返回太多結果,這也會相當快。

或者當你用一個條件快速說出時,你剛剛是指第一個嗎?

1

看起來你需要一個索引beta.product_id,除非這是你的主鍵嗎?

否則,你可以做到這一點作爲一個聯合查詢每一個具有不同的where子句:

SELECT DISTINCT `e`.*, `cat_index`.`position` AS `cat_index_position`, `price_index`.`price`, 
    `price_index`.`tax_class_id`, `price_index`.`final_price`, IF(price_index.tier_price IS NOT 
    NULL, LEAST(price_index.min_price, price_index.tier_price), 
    price_index.min_price) AS `minimal_price`, `price_index`.`min_price`, 
    `price_index`.`max_price`, `price_index`.`tier_price` 
FROM `catalog_product_entity` AS `e` 
INNER JOIN `catalog_category_product_index` AS `cat_index` ON cat_index.product_id=e.entity_id 
     AND cat_index.store_id=1 AND cat_index.visibility IN(2, 4) AND cat_index.category_id='2' 
INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id 
    AND price_index.website_id = '1' AND price_index.customer_group_id = 0 
LEFT JOIN `beta_entity_product` AS `beta` ON e.entity_id = beta.product_id AND beta.entity_id IN (81558,81559,84592,84593,87758,87759,87760,87761,90944,90945,90946,90947,94364,94365,94366,94367,98458,98459,98460,98461,98462,98463,104194,104195,104196,104197,110151,110152,110153,110154,110155,110156,116583,116584,116585,116586,123366,123367,123368,123369,123370,123371,123372,123373,130500,130501,130502,130503,130504,130505,130506,138075,138076,138077,138078,138079,138080,146179,146180,146181,146182,146183,146184,154543,154544,154545,154546,154547,154548,154549,154550,163639,163640,163641,163642,163643,163644,163645,173998,173999,174000,174001,174002,174003,174004,174005,174006,174007,184545,184546,184547,184548,184549,184550,195249,195250,195251,195252,195253,195254,195255,195256,195257,195258,206400,206401,206402,206403,206404,206405,217632,217633,217634,217635,217636,217637,217638,217639,229029,229030,229031,229032,229033,229034,229035,229036,229037,229038,229039,229040,240350,240351,240352,240353,240354,240355,240356,240357,240358,240359,240360,240361,251631,251632,251633,251634,251635,251636,251637,251638,251639,262900,262901,262902,262903,262904,262905,262906,262907,262908,262909,274205,274206,274207,274208,274209,274210,274211,274212,274213,274214,274215,274216,274217,285747,285748,285749,285750,285751,285752,285753,285754,285755,285756,285757,285758,297747,297748,297749,297750,297751,297752,297753,297754,297755,297756,297757,297758,297759,297760,297761,309660,309661,309662,309663,309664,309665,309666,309667,322314,322315,322316,322317,322318,322319,322320,322321,334814,334815,334816,334817,334818,334819,334820,334821,334822,334823,334824,334825,334826,346810,346811,346812,346813,346814,346815,346816,346817,346818,346819,346820,346821,358550,358551,358552,358553,358554,358555,358556,358557,358558,358559,358560,358561,358562,370376,370377,370378,370379,370380,370381,370382,370383,370384,370385,370386,370387,381938,381939,381940,381941,381942,381943,381944,381945,381946,381947,381948,381949,381950,391081,391082,391083,391084,391085,391086,391087,391088,391089,391090,391091,391092,391093,396111,396112,396113,396114,396115,396116,396117,396118,396119,396120,396121,396122,396123,396124,396125) 
LEFT JOIN `catalog_product_entity_int` AS `is_uni` ON e.entity_id = is_uni.entity_id AND attribute_id = 179 


WHERE is_uni.value = 1 
UNION 
SELECT DISTINCT `e`.*, `cat_index`.`position` AS `cat_index_position`, `price_index`.`price`, 
    `price_index`.`tax_class_id`, `price_index`.`final_price`, IF(price_index.tier_price IS NOT 
    NULL, LEAST(price_index.min_price, price_index.tier_price), 
    price_index.min_price) AS `minimal_price`, `price_index`.`min_price`, 
    `price_index`.`max_price`, `price_index`.`tier_price` 
FROM `catalog_product_entity` AS `e` 
INNER JOIN `catalog_category_product_index` AS `cat_index` ON cat_index.product_id=e.entity_id 
     AND cat_index.store_id=1 AND cat_index.visibility IN(2, 4) AND cat_index.category_id='2' 
INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id 
    AND price_index.website_id = '1' AND price_index.customer_group_id = 0 
LEFT JOIN `beta_entity_product` AS `beta` ON e.entity_id = beta.product_id AND beta.entity_id IN (81558,81559,84592,84593,87758,87759,87760,87761,90944,90945,90946,90947,94364,94365,94366,94367,98458,98459,98460,98461,98462,98463,104194,104195,104196,104197,110151,110152,110153,110154,110155,110156,116583,116584,116585,116586,123366,123367,123368,123369,123370,123371,123372,123373,130500,130501,130502,130503,130504,130505,130506,138075,138076,138077,138078,138079,138080,146179,146180,146181,146182,146183,146184,154543,154544,154545,154546,154547,154548,154549,154550,163639,163640,163641,163642,163643,163644,163645,173998,173999,174000,174001,174002,174003,174004,174005,174006,174007,184545,184546,184547,184548,184549,184550,195249,195250,195251,195252,195253,195254,195255,195256,195257,195258,206400,206401,206402,206403,206404,206405,217632,217633,217634,217635,217636,217637,217638,217639,229029,229030,229031,229032,229033,229034,229035,229036,229037,229038,229039,229040,240350,240351,240352,240353,240354,240355,240356,240357,240358,240359,240360,240361,251631,251632,251633,251634,251635,251636,251637,251638,251639,262900,262901,262902,262903,262904,262905,262906,262907,262908,262909,274205,274206,274207,274208,274209,274210,274211,274212,274213,274214,274215,274216,274217,285747,285748,285749,285750,285751,285752,285753,285754,285755,285756,285757,285758,297747,297748,297749,297750,297751,297752,297753,297754,297755,297756,297757,297758,297759,297760,297761,309660,309661,309662,309663,309664,309665,309666,309667,322314,322315,322316,322317,322318,322319,322320,322321,334814,334815,334816,334817,334818,334819,334820,334821,334822,334823,334824,334825,334826,346810,346811,346812,346813,346814,346815,346816,346817,346818,346819,346820,346821,358550,358551,358552,358553,358554,358555,358556,358557,358558,358559,358560,358561,358562,370376,370377,370378,370379,370380,370381,370382,370383,370384,370385,370386,370387,381938,381939,381940,381941,381942,381943,381944,381945,381946,381947,381948,381949,381950,391081,391082,391083,391084,391085,391086,391087,391088,391089,391090,391091,391092,391093,396111,396112,396113,396114,396115,396116,396117,396118,396119,396120,396121,396122,396123,396124,396125) 
LEFT JOIN `catalog_product_entity_int` AS `is_uni` ON e.entity_id = is_uni.entity_id AND attribute_id = 179 
WHERE beta.product_id IS NOT NULL 

根據您的數據,如果OR是互斥的數據,您可以將所有使用UNION。您正在運行的查詢無法充分利用INDEX MERGE,使OR語句快速運行所需的索引。

0

建議:

1)代替

beta.product_id IS NOT NULL 

not (beta.product_id IS NULL) 

2)您可以創建一個存儲過程或存儲功能,如果你想爲一個請求您的查詢。當然,您可以使用多個查詢,最後使用單個數據庫服務器請求合併部分結果。 3.如果你有複雜的數據庫邏輯,使用ORM,如Flourish

祝你好運。