2010-07-12 71 views
1

我有ORDER BY子句的問題。當我在下面的查詢中刪除ORDER BY時,查詢在0.004秒內完成。 如果我保留它,查詢運行非常慢= 56秒。這是因爲MySQL首先抓取所有500000條記錄,然後排序並最終回溯到前18條記錄。大表緩慢的ORDER BY

我該如何解決這個大表訂購問題?

謝謝。

解釋: http://img444.imageshack.us/img444/9440/explain.png

SQL查詢:

SELECT `_sd`.`sazbaDPHId`, `_sd`.`sazbaDPH`, `_sd`.`sazbaDPHProcent`, `_zk`.`zboziKategorieId`, `_zk`.`zboziId`, 
    `_zk`.`kategorieId`, `_zk`.`zboziKategoriePoradi`, `_k`.`kategorieId`, `_k`.`kategorieNazev`, `_k`.`kategorieCelyNazev`, 
    `_k`.`kategorieKod`, `_k`.`kategorieCesta`, `_k`.`kategoriePopis`, `_k`.`kategorieKeywords`, `_k`.`kategorieRodiceId`, `_k`.`kategoriePoradi`, `_k`.`kategorieSkryta`, `_k`.`kategorieVTopMenu`, `_v`.`vyrobceId`, `_v`.`vyrobceNazev`, `_v`.`vyrobceKod`, 
    `_v`.`vyrobceKoeficient`, `_tzvz`.`typZboziVlastnostZboziId`, `_tzvz`.`typZboziId`, `_tzvz`.`vlastnostZboziId`, 
    `_vzh`.`vlastnostZboziHodnotaId`, `_vzh`.`zboziId`, `_vzh`.`vlastnostZboziId`, `_vzh`.`vlastnostZboziHodnota`, `zvc`.`zboziVyslCenaId` AS`zvc_zboziVyslCenaId`, `zvc`.`zboziVyslCenaZboziId` AS`zvc_zboziVyslCenaZboziId`, `zvc`.`vyslCena` AS`zvc_vyslCena`, 
    `zvc`.`vyslCenaSDPH` AS`zvc_vyslCenaSDPH`, `this`.`zboziId`, `this`.`zboziNazev`, `this`.`zboziKod`, `this`.`zboziIdentifikator`, 
    `this`.`zboziPartNum`, `this`.`zboziEAN`, `this`.`zboziPopis`, `this`.`zboziOstatniParametry`, `this`.`zboziInterniInfo`, 
    `this`.`zboziProdejniCena`, `this`.`zboziAkcniCena`, `this`.`zboziSetovaCena`, `this`.`zboziMocCena`, `this`.`sazbaDPHId`, 
    `this`.`vyrobceId`, `this`.`typZboziId`, `this`.`stavZboziId`, `this`.`skladovaDostupnostId`, `this`.`zdrojCenId`, `this`.`zboziPHE`, 
    `this`.`zboziAutorskyPoplatek`, `this`.`zboziVahovyPoplatek`, `this`.`nemenitStavZbozi` 
    FROM `tbl_Zbozi`AS this 
    LEFT JOIN `reg_SazbaDPH`AS _sd ON this.sazbaDPHId = _sd.sazbaDPHId 
    LEFT JOIN `tbl_Zbozi_Kategorie`AS _zk ON this.zboziId = _zk.zboziId 
    LEFT JOIN `tbl_Kategorie`AS _k ON _zk.kategorieId = _k.kategorieId 
    LEFT JOIN `tbl_Vyrobce`AS _v ON this.vyrobceId = _v.vyrobceId 
    LEFT JOIN `tbl_TypZbozi_VlastnostZbozi`AS _tzvz ON this.typZboziId = _tzvz.typZboziId 
    LEFT JOIN `tbl_VlastnostZboziHodnota`AS _vzh ON this.zboziId = _vzh.zboziId AND _vzh.vlastnostZboziId = _tzvz.vlastnostZboziId 
    LEFT JOIN `tbl_Zbozi_VyslCena`AS zvc ON this.zboziId = zvc.zboziVyslCenaZboziId 
    WHERE _k.kategorieId IN (155317, 5570, 155445, 5706, 5707, 155429, 155430, 155431, 5708, 5709, 5710, 155427, 155426, 155428, 11413, 5713, 
    5714, 5715, 5716, 5717, 5718, 5719, 5720, 10245, 10253, 11253, 10834, 10269, 10249, 10246, 10247, 10248, 5723, 5725, 5726, 5727, 5728, 5729,   
    155319, 5815, 5816, 5817, 5818, 5819, 5822, 5824, 5832, 11406, 11411, 11410, 11409, 
    6069, 6070, 6072, 6073, 6075, 6078, 6086, 11414, 6185, 155433, 6186, 6187, 6188, 6190, 6191, 6193, 6198, 6199, 6200, 6201, 6202, 6203, 6207, 
    6209, 11442, 6210, 6211, 6212, 6215, 6216, 6217, 6218, 6219, 6220, 155366, 6221, 11339, 11340, 11341, 11359, 6222, 6223, 6224, 6225, 6226, 
    6227, 6228, 11099, 155376, 6231, 6232, 6233, 6234, 6235, 6236, 155391, 155392, 155437, 6237, 6238, 6241, 6243, 6244, 6245, 6246, 6247, 6248, 
    6249, 6250, 6251, 6252, 6253, 6254, 6256, 6257, 6258, 6259, 6260, 6261, 10839, 155362, 6262, 6263, 6264, 6265, 155361, 6267, 6269, 11390, 
    11346, 11112, 11394, 11397, 155393, 6270, 11436, 10292, 6271, 6272, 6275, 6277, 6278, 6279, 6280, 6281, 11348, 10288, 11113, 6283, 6284, 
    6285, 6287, 155494, 11114, 6292, 6293, 6294, 6295, 6296, 6297, 6298, 6300, 6301, 6302, 6303, 6304, 11116, 6305, 10781, 6306, 6307, 6308, 
    6309, 6310, 6311, 6313, 6314, 6315, 6316, 6317, 6318, 6327, 6328, 155451, 6333, 6334, 6335, 6337, 6340, 6342, 6343, 6344, 6345, 6346, 11344, 
    11389, 10289, 10291, 10302, 10303, 10304, 10294, 10306, 10300, 10305, 10293, 10299, 10298, 10290, 10296, 10297, 11454, 11100, 11101, 
    11117, 131475, 11402, 5680, 5684, 5685, 5686, 5687, 5688, 5689, 11383, 5702, 5703, 5704, 5705) 
AND stavZboziId IN (2) 
AND zvc.zboziVyslCenaSkupinaId = '8' 
ORDER BY _k.kategoriePoradi ASC LIMIT 18 
+0

粘貼輸出加速這一過程。 – Naktibalda 2010-07-12 12:54:09

+0

我附上了解釋結果截圖 – 2010-07-12 13:19:17

+0

我不知道MySQL中的等價物是什麼。但是在MSSQL中,您可以通過查詢計劃將查詢劃分爲更小的部分,並描述每個部分的操作和整體影響。在嘗試優化查詢時,查看類似的內容比擊中或錯過更改要好。 – 2010-07-12 13:24:18

回答

3

還能怎樣工作的?如果它在選擇了18條記錄後應用了訂單,則會以默認訂單的形式獲得排名前18的記錄,然後進行排序。

IN語句中的所有值插入臨時表中,然後連接到臨時表,可能會獲得更好的性能。

+0

感謝Ben,我試過了,但它只把時間縮短到了45秒。 – 2010-07-12 13:05:23

2

它仍然有50萬點的記錄排序,找到你18所以它會慢很多,你可以通過在你的表添加索引到你的kategoriePoradi柱解釋查詢的

+0

謝謝Dave,我將BTREE索引添加到kategoriePoradi,但我沒有得到任何性能。 但是我有所有WHERE/JOIN列的索引。 – 2010-07-12 13:04:11