2010-07-12 6 views
1

У меня проблема с предложением ORDER BY. Когда я удаляю ORDER BY в следующем запросе, запрос завершается в 0.004 секунды. Если я его сохраню, запрос работает очень медленно = 56 секунд. Это потому, что MySQL сначала захватывает все 500 000 записей, затем сортирует и, наконец, сохраняет только первые 18 записей.Slow ORDER BY in large table

Как я могу решить эту проблему с большим столом?

Спасибо.

Объясните: 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

Вставить вывод EXPLAIN для запроса. – Naktibalda

+0

Я приложил объяснение результатов скриншот –

+0

Я не знаю, что эквивалентно в MySQL. но в MSSQL вы можете заставить его выплюнуть план запроса, который разбивает запрос на более мелкие части и описывает, какие операции и общее влияние будут иметь каждая часть. Глядя на что-то подобное, лучше, чем ударить или пропустить изменения при попытке оптимизировать запрос. –

ответ

3

Как еще это может работать? Если он применил заказ после выбора 18 записей, вы получили бы 18 записей в порядке по умолчанию, которые он затем сортировал.

Вы можете получить лучшую производительность, вставив все значения в свой оператор IN в таблицу темпа, а затем присоединитесь к таблице temp.

+0

Спасибо, Бен, я попробовал, но это сократило время до 45 секунд. –

2

он все еще должен сортировать 500000 записей, чтобы найти ваш 18, так что будет много медленнее, вы можете ускорить его путем добавления индексов в столбце kategoriePoradi в таблицах

+0

Спасибо Дэйв, я добавил индекс BTREE к категории Поради, но я не получил никакой производительности. Однако у меня есть индексы во всех столбцах WHERE/JOIN. –