【问题标题】:to accelerate mysql query加速mysql查询
【发布时间】:2015-07-31 08:42:42
【问题描述】:

我在 MySQL 中有这个查询。此查询运行时间过长,我知道问题出在选择器(coalesce ((SELECT ...),我不知道如何通过连接加快查询速度。

我希望你们中的一些 SQL 专家能够帮助我。

SELECT
    COALESCE(
        (SELECT CONCAT(d.PRIJEVOZNIK, ' ', d.VOZAC_TRANSFER) 
         FROM dokum_zag as d
         where d.SIFKNJ='NP' and
               d.ID_VEZA=dokum_zag.ID and 
               d.korisnicko_ime=dokum_zag.korisnicko_ime 
         ),'') as PRIJEVOZNIK,
      (RELACIJA_TRANS_VOZ_TRANS) as RELACIJA_TRANS_VOZ, 
      (PRIJEVOZNIK_POVRATNI_TRANS) as PRIJEVOZNIK_POVRATNI, 
      (VAUC_KNJIZENO_TRANS) as VAUC_KNJIZENO, 
      ID_NALOGA, 
      ID_NALOGA_POV, 
      ID_VAUCHER, 
      DOLAZAK, VRIJ_TRANSFER,ODLAZAK,VRIJEME_LETA_POVRAT ,BRDOK, NOSITELJ_REZ, RELACIJA_TRANS, VOZILO_NAZIV, BROJ_NALOGA,BROJ_NAL_POV,BROJ_VAUCHER,BROJ_SOBE,VALIZN,PAX, MPIZN,ID 
FROM
    dokum_zag 
WHERE 
    korisnicko_ime = '10' and 
    ((DOLAZAK='2015-07-30') or (ODLAZAK='2015-07-30')) and 
    STORNO <> 'DA' and 
    SIFKNJ = 'TR' and 
   ((YEAR(DOLAZAK)= '2015') or (YEAR(ODLAZAK)= '2015')) 
order by 
   (CASE WHEN DOLAZAK < '2015-07-30' THEN ODLAZAK ELSE DOLAZAK END) , 
   (CASE WHEN DOLAZAK < '2015-07-30' THEN VRIJEME_LETA_POVRAT ELSE VRIJ_TRANSFER END), ID 

【问题讨论】:

    标签: php mysql join query-optimization


    【解决方案1】:

    如果没有数据库结构,并且对您要提取的内容的描述,它对您的帮助有点困难。

    从逻辑的角度来看,有些东西是多余的,例如

    ((DOLAZAK='2015-07-30') or (ODLAZAK='2015-07-30')) and 
    ...
    ((YEAR(DOLAZAK)= '2015') or (YEAR(ODLAZAK)= '2015')) 
    

    年份部分不是必需的,因为年份是在前两个中指定的。

    另一件可能让服务器发疯的事情是那个奇怪的order by 子句,因为它在记录之间发生变化(测试它在字段上固定的这个设置)。

    您还可以检查是否为外部where 子句中的所有字段正确设置了索引,以及那些不是数字的,不是varchars(例如SIFKNJSTORNO 应该是char(2) )。

    coalesce 部分可以通过outer join 解决,因此不会对每一行进行计算。但这取决于你想从数据库中提取什么以及如何提取......(因为该子查询在 where 部分有它自己的字段......很奇怪)

    希望这能有所帮助

    【讨论】:

    • SIFKNJ 和 STORNO 是 char(2), (YEAR(DOLAZAK)= '2015') 或 (YEAR(ODLAZAK)= '2015') 我搬走了,查询执行时间是 8.2504 秒,如果剥离(coalesce ((SELECT ...),查询执行时间0.3559秒,
    • 表dokum_zag,有223957条记录,
    【解决方案2】:
    INDEX(korisnicko_ime, SIFKNJ)
    

    (以任意顺序)可能会有所帮助

    将相关子查询转换为 JOIN 可能会有所帮助。

    ((DOLAZAK='2015-07-30') or (ODLAZAK='2015-07-30')) and 
    ((YEAR(DOLAZAK)= '2015') or (YEAR(ODLAZAK)= '2015')) 
    

    有点奇怪。这可能会有所帮助:

    ( SELECT ... 
         AND DOLAZAK ='2015-07-30' AND ODLAZAK >= '2015-01-01'
                                   AND ODLAZAK  < '2015-01-01' + INTERVAL 1 YEAR
    ) UNION DISTINCT
    ( SELECT ... 
         AND ODLAZAK ='2015-07-30' AND DOLAZAK >= '2015-01-01'
                                   AND DOLAZAK  < '2015-01-01' + INTERVAL 1 YEAR
    ) ORDER BY ...
    

    为了帮助重新制定,添加 2 个复合索引:

    INDEX(korisnicko_ime, SIFKNJ, DOLAZAK, ODLAZAK)
    INDEX(korisnicko_ime, SIFKNJ, ODLAZAK, DOLAZAK)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-28
      • 2014-03-17
      • 2012-08-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多