繁体   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