【发布时间】:2017-07-07 19:00:28
【问题描述】:
我有一个 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
更新
我可以使用FROM ki_ka_ot, ki_il, ka_il, ki_ka, ka_ki_ot, kaa, ka_ki 并将几个AND 条件添加到WHERE 部分,而不是使用join。查询的结果将 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
【问题讨论】:
-
您没有索引:添加索引通常会有所帮助
-
@NorbertvanNobelen 是的,我明白了。我的查询范围很广,以至于我不知道应该创建哪些索引。
-
索引应该在你加入的值上创建。其他的(大部分时间)无关紧要。
-
是的,这应该会有所帮助:不能保证它会很好,但是任何连接性能都需要索引
-
如果你想要这个结果,我会运行所有连接的查询。如果它真的很慢,我会分析并查看是否可以通过拆分查询来优化它,也许将其保存到一些方便的可重用表中,并与这些表一起工作以获得最终结果。