使用join时MySQL查询速度要慢得多

时间:2017-07-07 19:00:28

标签: mysql sql database

我有一个MySQL数据库和一个我正在尝试优化的查询。

我不熟悉索引,所以我不知道应该创建哪些索引。目前我没有任何索引,我认为我的查询太慢了。事实上,使用join使得这一切变慢了。我相信它会让这更快,但不会。我不明白为什么现在这个慢得多。

对索引的任何建议?还有什么我可以更好地让我的查询更快?

            SELECT ka_ki.kierrosnumero AS kierrosnumero
            , ka_ki.kierroskoodi AS kierroskoodi
            , ka_ki_ot.ottelunumero AS ottelunumero
            , ka_ki.haviajien_sijat_tekstina AS haviajien_sijat_tekstina
            , ka_ki.voittajien_puolelta_cupiin AS voittajien_puolelta_cupiin
            , ka_ki.haviajien_puolelta_cupiin AS haviajien_puolelta_cupiin
            , ka_ki_ot.paikka_a_ja_b_kaaviokoodi AS paikka_a_ja_b_kaaviokoodi 
            , ka_ki_ot.paikka_a_kaaviokoodi AS paikka_a_kaaviokoodi
            , ka_ki_ot.paikka_b_kaaviokoodi AS paikka_b_kaaviokoodi
            , ki_ka_ot.id AS ki_ka_ot_id
            , ki_ka_ot.kaaviopaikka_id
            , ki_ka_ot.peli_monesko_peli_ottelussa
            , ki_ka_ot.peli_pelipaikka_id
            , ki_ka_ot.peli_pelimuoto_id
            , ki_ka_ot.peli_voittopisteet
            , ki_ka_ot.peli_ajankohta_aikataulutus
            , ki_ka_ot.peli_ajankohta_alkamisaika
            , ki_ka_ot.peli_ajankohta_loppumisaika
            , ki_ka_ot.peli_paikka_a_tiimiilmo_id
            , ki_ka_ot.peli_paikka_b_tiimiilmo_id
            , ki_ka_ot.peli_paikka_a_peluri1ilm_id
            , ki_ka_ot.peli_paikka_a_peluri2ilm_id
            , ki_ka_ot.peli_paikka_b_peluri1ilm_id
            , ki_ka_ot.peli_paikka_b_peluri2ilm_id
            , ki_il.pari_joukkue_nimi_txt AS peli_paikka_b_pari_joukkue_nimi_txt
            , ki_il.sijoitusnumero_syotetty AS peli_paikka_b_sijoitusnumero_syotetty
            , ki_il.sijoitusnumero_arvottu AS peli_paikka_b_sijoitusnumero_arvottu
            , ka_il.pelaaja_oma_nimi_txt AS peli_paikka_b_peluri1_oma_nimi_txt
            FROM ki_ka_ot
                    JOIN ki_il ON ki_ka_ot.peli_paikka_b_tiimiilmo_id = ki_il.id
                    JOIN ka_il ON ki_ka_ot.peli_paikka_b_peluri1ilm_id = ka_il.id
                    JOIN ki_ka ON ki_ka.id = ki_ka_ot.kaavio_id
                    JOIN ka_ki_ot ON 
                            ki_ka.kaaviopohja_id = ka_ki_ot.kaaviopohja_id
                            AND ka_ki_ot.id = ki_ka_ot.kaaviopaikka_id
                    JOIN kaa ON ka_ki_ot.kaaviopohja_id = kaa.id
                    JOIN ka_ki ON ka_ki_ot.kierros_id = ka_ki.id
            WHERE ki_ka_ot.kaavio_id = 107
            ORDER BY ka_ki_ot.ottelunumero ASC

更新

我可以使用join而不是使用FROM ki_ka_ot, ki_il, ka_il, ki_ka, ka_ki_ot, kaa, ka_ki,并向AND部分添加多个WHERE条件。查询的结果将是100%相同,但它会更快。我应该这样做吗?

            SELECT ka_ki.kierrosnumero AS kierrosnumero
            , ka_ki.kierroskoodi AS kierroskoodi
            , ka_ki_ot.ottelunumero AS ottelunumero
            , ka_ki.haviajien_sijat_tekstina AS haviajien_sijat_tekstina
            , ka_ki.voittajien_puolelta_cupiin AS voittajien_puolelta_cupiin
            , ka_ki.haviajien_puolelta_cupiin AS haviajien_puolelta_cupiin
            , ka_ki_ot.paikka_a_ja_b_kaaviokoodi AS paikka_a_ja_b_kaaviokoodi 
            , ka_ki_ot.paikka_a_kaaviokoodi AS paikka_a_kaaviokoodi
            , ka_ki_ot.paikka_b_kaaviokoodi AS paikka_b_kaaviokoodi
            , ki_ka_ot.id AS ki_ka_ot_id
            , ki_ka_ot.kaaviopaikka_id
            , ki_ka_ot.peli_monesko_peli_ottelussa
            , ki_ka_ot.peli_pelipaikka_id
            , ki_ka_ot.peli_pelimuoto_id
            , ki_ka_ot.peli_voittopisteet
            , ki_ka_ot.peli_ajankohta_aikataulutus
            , ki_ka_ot.peli_ajankohta_alkamisaika
            , ki_ka_ot.peli_ajankohta_loppumisaika
            , ki_ka_ot.peli_paikka_a_tiimiilmo_id
            , ki_ka_ot.peli_paikka_b_tiimiilmo_id
            , ki_ka_ot.peli_paikka_a_peluri1ilm_id
            , ki_ka_ot.peli_paikka_a_peluri2ilm_id
            , ki_ka_ot.peli_paikka_b_peluri1ilm_id
            , ki_ka_ot.peli_paikka_b_peluri2ilm_id
            , ki_il.pari_joukkue_nimi_txt AS peli_paikka_b_pari_joukkue_nimi_txt
            , ki_il.sijoitusnumero_syotetty AS peli_paikka_b_sijoitusnumero_syotetty
            , ki_il.sijoitusnumero_arvottu AS peli_paikka_b_sijoitusnumero_arvottu
            , ka_il.pelaaja_oma_nimi_txt AS peli_paikka_b_peluri1_oma_nimi_txt
            FROM ki_ka_ot
            , ki_il
            , ka_il
            , kaa
            , ka_ki
            , ka_ki_ot
            , ki_ka
            WHERE ki_ka_ot.kaavio_id = 107
            AND ki_ka_ot.peli_paikka_b_tiimiilmo_id = ki_il.id
            AND ki_ka_ot.peli_paikka_b_peluri1ilm_id = ka_il.id
            AND ki_ka.id = ki_ka_ot.kaavio_id
            AND ki_ka.kaaviopohja_id = ka_ki_ot.kaaviopohja_id
            AND ka_ki_ot.kaaviopohja_id = kaa.id 
            AND ka_ki_ot.kierros_id = ka_ki.id
            AND ka_ki_ot.id = ki_ka_ot.kaaviopaikka_id
            ORDER BY ka_ki_ot.ottelunumero ASC

更新2

现在我修改了使用join的原始查询。我认为它工作得更好更快,但也许有一些东西需要解决。

            SELECT ka_ki.kierrosnumero AS kierrosnumero
            , ka_ki.kierroskoodi AS kierroskoodi
            , ka_ki_ot.ottelunumero AS ottelunumero
            , ka_ki.haviajien_sijat_tekstina AS haviajien_sijat_tekstina
            , ka_ki.voittajien_puolelta_cupiin AS voittajien_puolelta_cupiin
            , ka_ki.haviajien_puolelta_cupiin AS haviajien_puolelta_cupiin
            , ka_ki_ot.paikka_a_ja_b_kaaviokoodi AS paikka_a_ja_b_kaaviokoodi 
            , ka_ki_ot.paikka_a_kaaviokoodi AS paikka_a_kaaviokoodi
            , ka_ki_ot.paikka_b_kaaviokoodi AS paikka_b_kaaviokoodi
            , ki_ka_ot.id AS ki_ka_ot_id
            , ki_ka_ot.kaaviopaikka_id
            , ki_ka_ot.peli_monesko_peli_ottelussa
            , ki_ka_ot.peli_pelipaikka_id
            , ki_ka_ot.peli_pelimuoto_id
            , ki_ka_ot.peli_voittopisteet
            , ki_ka_ot.peli_ajankohta_aikataulutus
            , ki_ka_ot.peli_ajankohta_alkamisaika
            , ki_ka_ot.peli_ajankohta_loppumisaika
            , ki_ka_ot.peli_paikka_a_tiimiilmo_id
            , ki_ka_ot.peli_paikka_b_tiimiilmo_id
            , ki_ka_ot.peli_paikka_a_peluri1ilm_id
            , ki_ka_ot.peli_paikka_a_peluri2ilm_id
            , ki_ka_ot.peli_paikka_b_peluri1ilm_id
            , ki_ka_ot.peli_paikka_b_peluri2ilm_id
            , ki_il.pari_joukkue_nimi_txt AS peli_paikka_b_pari_joukkue_nimi_txt
            , ki_il.sijoitusnumero_syotetty AS peli_paikka_b_sijoitusnumero_syotetty
            , ki_il.sijoitusnumero_arvottu AS peli_paikka_b_sijoitusnumero_arvottu
            , ka_il.pelaaja_oma_nimi_txt AS peli_paikka_b_peluri1_oma_nimi_txt
            FROM ki_ka_ot
                    JOIN ki_il ON ki_ka_ot.peli_paikka_b_tiimiilmo_id = ki_il.id
                    JOIN ka_il ON ki_ka_ot.peli_paikka_b_peluri1ilm_id = ka_il.id
                    JOIN ki_ka ON ki_ka.id = ki_ka_ot.kaavio_id
                    JOIN ka_ki_ot ON 
                            ki_ka.kaaviopohja_id = ka_ki_ot.kaaviopohja_id
/* AND ka_ki_ot.id = ki_ka_ot.kaaviopaikka_id */
                    JOIN kaa ON ka_ki_ot.kaaviopohja_id = kaa.id
                    JOIN ka_ki ON ka_ki_ot.kierros_id = ka_ki.id
            WHERE ki_ka_ot.kaavio_id = 107
AND ka_ki_ot.id = ki_ka_ot.kaaviopaikka_id /* this was moved here */
            ORDER BY ka_ki_ot.ottelunumero ASC

1 个答案:

答案 0 :(得分:1)

JOIN是一项高成本操作,尽管优化程序尝试有效执行,但如果没有数据上下文,则无法实现。我不能建议您应该制作特定的索引,因为我也没有您的数据上下文,但您应该尝试以影响您希望执行的任何操作的方式进行索引。因此,如果您在A列上加入JOIN,则您希望在A上编制索引,以便优化程序可以有效地执行JOIN