簡體   English   中英

即使有限制,Mysql 查詢也需要很長時間

[英]Mysql query taking long time even with LIMITS

1. 總結問題

我們公司已經使用這個系統很長時間了,人們感覺系統速度非常慢。 我無法重寫代碼,因為它的超級硬編碼和太多文件無法重寫。

幾個月前,我們看到一個查詢的執行時間大約為 170 秒。 我的解決方法是為每個查詢添加 LIMITS,從 170 秒減少到 2-3 秒。 但上周我看到該代碼現在需要大約 5-25 秒。

該系統也在 php 5.2 上。 基本上不可能升級代碼以供 5.6 人使用 3 個人正在重寫此代碼,8 小時后我們設法登錄頁面。 索引是有限的,因為大多數數據庫信息都是字符串而不是整數。

2. 提供背景,包括您已經嘗試過的內容

我試過的:
- 默認添加限制 300,用戶也可以更改此限制。
- 將服務器遷移到更好的硬件。
- 提供更多 RAM(現在 10GB)和兩個虛擬 CPU。
- 從本地存儲遷移到網絡(此時性能更好)。

3. 顯示一些代碼

SELECT pastabos_apskaitininkui, 
       uzdaviniai.pakr_salis, 
       uzdaviniai.iskr_salis, 
       uzdaviniai.id                       AS uzdavinio_id, 
       salys.salis                         AS muitines_salis, 
       uzdaviniai.pakr_regionas, 
       uzdaviniai.iskr_regionas, 
       uzdaviniai.pakr_miestas, 
       uzdaviniai.iskr_miestas, 
       uzdavinio_priekaba, 
       priekabos.tipas                     AS priekabos_tipas, 
       uzdaviniai.kas_sukure_skyrius, 
       uzdaviniai.kam_sukure_skyrius, 
       uzdaviniai.kas_sukure_vadyb, 
       uzdaviniai.kam_sukure_vadyb, 
       uzdav_users.vardas_sutr             AS uzdav_user_vardas, 
       pakrov_salis.sutrumpinimas          AS uzdav_pakr_salis, 
       iskrov_salis.sutrumpinimas          AS uzdav_iskr_salis, 
       uzdaviniai.pasikrovimo_data         AS uzd_pasikrovimo_data, 
       uzdaviniai.pristatymo_data          AS uzd_pristatymo_data, 
       uzdaviniai.pastabos, 
       suma_vykdytojui_valiuta, 
       vykdytojui_valiuta, 
       uzdaviniai.eil_nr, 
       uzdaviniai.statusas, 
       uzdaviniai.statusas_baigtas_ranka, 
       keliones_lapas.reiso_nr, 
       keliones_lapas.masina, 
       keliones_lapas.masinos_id, 
       keliones_lapas.priekabos_nr, 
       keliones_lapas.priekabos_id, 
       keliones_lapas.priekabos2_nr, 
       keliones_lapas.reiso_pavadinimas, 
       keliones_lapas.vykdytojo_tipas, 
       keliones_lapas.vykdytojo_imone, 
       keliones_lapas.atvykimo_data, 
       keliones_lapas.vairuotojas, 
       keliones_lapas.vairuotojas2, 
       keliones_lapas.vairuotojas3, 
       keliones_lapas.vairuotojas4, 
       keliones_lapas.marsrutas, 
       klientai.firmos_pavadinimas         AS uzsakovas, 
       uzsakovo_uzs_nr, 
       valiutos.valiuta                    AS frachto_valiuta, 
       uzsakymas.vadybininkas, 
       uzsakymas.skyrius, 
       uzsakymas.frachtas_suma, 
       uzsakymas.pavadinimas, 
       uzsakymas.uzsakymo_id, 
       uzsakymas.reg_data, 
       uzsakymas.pastabos                  AS uzs_pastabos, 
       uzsakymas.statusas                  AS uzsakymo_statusas, 
       sask_ist.serija, 
       sask_ist.sask_nr, 
       sask_ist.id                         AS sask_id, 
       sask_ist.suma, 
       sask_ist.valiuta, 
       sask_ist.kursas                     AS sask_ist_kursas, 
       sask_ist.apmoketi_iki, 
       sask_ist.atidejimas, 
       issiuntimo_data, 
       sask_ist_apmokejimas.suma           AS ist_apm_suma, 
       sask_ist_apmokejimas.valiuta        AS ist_apm_valiuta, 
       sask_ist_apmokejimas.kursas         AS ist_apm_kursas, 
       sask_ist_apmokejimas.id             AS ist_apm_id, 
       klientu_pakr_vietos.pavadinimas     AS muitines_pavadinimas, 
       klientu_pakr_vietos.miestas         AS muitines_miestas, 
       klientu_pakr_vietos.adresas         AS muitines_adresas, 
       kokio_krovinio_dalis, 
       krovinys_konsoliduotas, 
       kroviniu_tipai.pavadinimas          AS krovinio_pavadinimas, 
       kroviniai.pasikrovimo_data, 
       kroviniai.pristatymo_data, 
       kroviniai.uzsakovo_krovinio_nr, 
       kroviniai.id                        AS krovinio_id, 
       svoris_t, 
       ldm, 
       turis, 
       paleciu_skaicius, 
       vnt, 
       temperature, 
       kroviniai.konteinerio_nr, 
       kroviniai.pakr_vietos_id            AS kr_pakr_vietos_id, 
       kroviniai.iskr_vietos_id            AS kr_iskr_vietos_id, 
       kroviniai.pakr_salis                AS kr_pakr_salis, 
       kroviniai.iskr_salis                AS kr_iskr_salis, 
       kroviniai.pakr_miestas              AS kr_pakr_miestas, 
       kroviniai.pakr_regionas             AS kr_pakr_regionas, 
       kroviniai.iskr_regionas             AS kr_iskr_regionas, 
       kroviniai.iskr_miestas              AS kr_iskr_miestas, 
       kroviniai.ismuitinimo_data          AS ismuitinimo_data, 
       kroviniai.uzmuitinimo_data          AS uzmuitinimo_data, 
       kroviniai.pasienio_postas           AS pasienio_postas, 
       kroviniai.ismuitinimo_vieta         AS ismuitinimo_vieta, 
       statusai.pavadinimas                AS st_pavadinimas, 
       st_uzsakymai.id                     AS st_id, 
       st_salys.salis                      AS st_salis, 
       st_uzsakymai.data                   AS st_data, 
       st_uzsakymai.laikas                 AS st_laikas, 
       st_uzsakymai.ivykio_pastabos_sutr   AS st_pastabos_sutr, 
       st_uzsakymai.ivykio_pastabos        AS st_pastabos, 
       st_keliones_lapas.reiso_pavadinimas AS st_reiso_pav, 
       vairuotojai.vardas                  AS sq_vardas, 
       priekabos.masinos_nr                AS sq_priekaba 
FROM   uzdaviniai 
       LEFT JOIN priekabos 
              ON priekabos.id = uzdaviniai.uzdavinio_priekaba 
       LEFT JOIN users AS uzdav_users 
              ON uzdav_users.id = uzdaviniai.kam_sukure_vadyb 
       LEFT JOIN salys AS pakrov_salis 
              ON pakrov_salis.id = uzdaviniai.pakr_salis 
       LEFT JOIN salys AS iskrov_salis 
              ON iskrov_salis.id = uzdaviniai.iskr_salis 
       LEFT JOIN uzsakymas 
              ON uzdaviniai.uzsakymo_id = uzsakymas.uzsakymo_id 
       LEFT JOIN uzd_kur_vykdytas 
              ON uzdaviniai.id = uzd_kur_vykdytas.uzdavinio_id 
       LEFT JOIN keliones_lapas 
              ON keliones_lapas.reiso_nr = uzd_kur_vykdytas.reiso_nr 
       LEFT JOIN st_uzsakymai 
              ON st_uzsakymai.uzdavinio_id = uzdaviniai.id 
       LEFT JOIN statusai 
              ON statusai.id = st_uzsakymai.statuso_id 
       LEFT JOIN salys AS st_salys 
              ON st_salys.id = st_uzsakymai.salis 
       LEFT JOIN keliones_lapas AS st_keliones_lapas 
              ON st_keliones_lapas.reiso_nr = st_uzsakymai.reiso_nr 
       LEFT JOIN vairuotojai 
              ON vairuotojai.id = keliones_lapas.vairuotojas 
       LEFT JOIN sask_ist_uz_ka 
              ON sask_ist_uz_ka.uzsakymo_id = uzsakymas.uzsakymo_id 
       LEFT JOIN sask_ist 
              ON sask_ist.id = sask_ist_uz_ka.sask_id 
       LEFT JOIN sask_ist_apmokejimas 
              ON sask_ist.id = sask_ist_apmokejimas.sask_id 
       LEFT JOIN uzsakymo_kroviniai 
              ON uzsakymas.uzsakymo_id = uzsakymo_kroviniai.uzsakymo_id 
       LEFT JOIN kroviniai 
              ON kroviniai.id = uzsakymo_kroviniai.krovinio_id 
       LEFT JOIN klientu_pakr_vietos 
              ON klientu_pakr_vietos.id = kroviniai.ismuitinimo_vieta 
       LEFT JOIN klientu_pakr_vietos AS iskr_vietos_uzd 
              ON iskr_vietos_uzd.id = uzdaviniai.pakr_vietos_id 
       LEFT JOIN salys 
              ON salys.id = klientu_pakr_vietos.salis 
       LEFT JOIN cmr_kroviniai 
              ON kroviniai.id = cmr_kroviniai.krovinio_id 
       LEFT JOIN cmr 
              ON cmr.id = cmr_kroviniai.cmr_id 
       LEFT JOIN cmr_panaudojimas 
              ON cmr_panaudojimas.cmr_id = cmr_kroviniai.cmr_id 
                 AND keliones_lapas.reiso_nr = cmr_panaudojimas.reiso_nr 
       LEFT JOIN kroviniu_tipai 
              ON kroviniu_tipai.id = kroviniai.krovinio_pavadinimas 
       LEFT JOIN klientai 
              ON klientai.id = uzsakymas.kliento_id 
       LEFT JOIN valiutos 
              ON valiutos.id = uzsakymas.frachtas_valiuta 
WHERE  1 = 1 
       AND ( `uzdaviniai`.`pasikrovimo_data` BETWEEN 
             '2019-07-08' AND '2019-07-08 23:59:59' 
           ) 
ORDER  BY uzdaviniai.pasikrovimo_data DESC 
LIMIT  300

如您所見,有許多 left join 語句。

4. 結果

我想要的是一些幫助我可以用這塊廢話做什么或一些建議我可以改變什么。 正如我預計這些查詢將花費越來越多的時間來執行。

如果直接在mysql控制台執行查詢速度快,那么查詢完全沒有問題,慢的是使用查詢結果的php代碼,你沒有顯示的php代碼,你應該修改/在這里發帖。

如果即使在 mysql 控制台中查詢也很慢,那么問題可能是主表/聯接表的大小(但這可以通過放寬 mysql 服務器的內存限制和/或向服務器添加內存來解決),或者可能對連接表進行不正確的索引,因為任何 LEFT JOIN 都需要在用於連接它的字段上對連接表進行索引(這可以通過在連接表上創建正確的索引來解決)。

考慮改變你的

WHERE  1 = 1 
   AND ( `uzdaviniai`.`pasikrovimo_data` BETWEEN 
         '2019-07-08' AND '2019-07-08 23:59:59' 
       ) 

哪里uzdaviniai pasikrovimo_data BETWEEN '2019-07-08' 和 '2019-07-08 23:59:59'

請讓我們知道結果(帶反引號)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM