需要帮助优化查询

时间:2021-06-09 06:11:59

标签: mysql sql query-optimization

实际上我正在使用下面的查询来获取结果,但我觉得这是一个有点冗长的查询,我可以帮助优化下面的查询吗?

ID      LineID  TeamID  ShiftID DateTime        Production  Theoretical  Scrap
1       3       1       NULL    18/6/2020 4:00  482.5291    511.2351    
2       2       1       NULL    18/6/2020 5:00  467.8704    519.9842
3       1       1       NULL    18/6/2020 5:00  390.5945    480.2252    
2186    3       1       NULL    18/6/2020 5:00  0                        0.5
2520    2       1       NULL    18/6/2020 5:00  0                        21
2840    1       1       NULL    18/6/2020 6:00  0                        12
4       1       1       NULL    18/6/2020 6:00  389.2222    480.2252        
5       3       1       NULL    18/6/2020 6:00  516.0907    511.2351    
6       2       1       NULL    18/6/2020 6:00  450.5216    519.9842    
7       3       1       NULL    18/6/2020 6:00  397.9998    511.2351    
8       2       1       NULL    18/6/2020 7:00  456.9486    519.9842    
9       1       1       NULL    18/6/2020 7:00  414.6932    480.2252        
1939    2       1       NULL    18/6/2020 7:00  0                        24
2462    3       1       NULL    18/6/2020 7:00  0                        3
3075    1       1       NULL    18/6/2020 7:00  0                        3.5
1
......
......
......
114678  1       1       NULL    18/6/2018 22:00 343.5955    480.2252    
114798  3       1       NULL    18/6/2018 22:00 191.2512    511.2351        
114888  2       1       NULL    18/6/2018 22:00 190.5125    519.9842    
114657  2       1       NULL    18/6/2018 22:00 414.6432    519.9842
114738  1       1       NULL    18/6/2018 22:00 429.43      480.2252
114885  3       1       NULL    18/6/2018 23:00 361.3246    511.2351    
114756  1       1       NULL    18/6/2018 23:00 409.51      480.2252    

我正在使用多个连接,是否可以优化依赖子查询?

2 个答案:

答案 0 :(得分:0)

对查询的细微调整,例如将 select count() 调整到其自己的预查询/聚合,但仅针对有问题的一个机构。当您将某些 LEFT JOIN 添加到 WHERE 子句时,它们实际上变成了 INNER JOINS。

我实际上将 AND 部分移到了所连接的表的相应 JOIN 位置。

我会确保以下索引

table               index
InstitutionToOrder  (institutionid, orderid)
orders              (orderid, voided, suspended)
subscribeDates      (orderid, dateEnd )
OrderToSection      (orderid, sectionid )

此外,您不需要到处都是“AS”,例如列 AS resultColumn 或表 A​​S 别名。分别在项目后加一个空格隐含“AS”。

SELECT
        o.orderid id,
        sd.datestart startdate,
        sd.dateend enddate,
        o.comment,
        o.productname name,
        o.suspended sus,
        o.voided void,
        o.invoice_number inumber,
        GROUP_CONCAT(js.title) sections,
        GROUP_CONCAT(js.sectionid) sectionid,
        js.is_science_education isse,
        o.amount,
        js.isbundle,
        o.addedbyuserid,
        preCount.multiple
    FROM
        institutiontoorder ito
            JOIN orders o 
                ON ito.orderid = o.orderid
                AND o.voided = 0
                AND o.suspended = 0
            JOIN subscribedates sd 
                ON ito.orderid = sd.orderid
                AND sd.dateend >= NOW()
            JOIN
                -- pre-aggregate counts once for just the 
                -- institution in question and join to it
                ( SELECT
                        ito2.orderid,
                        COUNT(*) muliple
                    FROM
                        institutiontoorder ito2
                    WHERE
                        ito2.institutionid = '1419'
                    group by
                        ito2.orderid ) AS PreCount
                on ito.orderid = PreCount.orderid
            LEFT JOIN ordertosection ots 
                ON ito.orderid = ots.orderid
                JOIN journalsections js 
                    ON ots.sectionid = js.sectionid
            LEFT JOIN institutions i 
                ON ito.institutionid = i.institutionid
    WHERE
        ito.institutionid = '1419'
    GROUP BY
        -- via Transitive Property, since o.orderid = ito.orderid,
        -- use the primary table in the query's orderID for group/order by
        ito.orderid
    ORDER BY 
        ito.orderid DESC;

根据 O. Jones 的评论,我完全同意对您订单的 VOIDED 和 SUSPENDED 过滤器进行不等式测试。这些值的选择是什么...只有 0 或 1,其中 1 表示 VOIDED 或 SUSPENDED?或者他们有其他价值。我已调整为相等 = 0(意味着未作废和未暂停)

答案 1 :(得分:0)

o:    (orderid, dateend)
ito:  (institutionid, orderid)
ots:  (orderid, sectionid)
js:   (sectionid, isbundle, is_science_education, title)
i:    (institutionid)
sd:   (orderid, dateend, datestart)

列的顺序通常很重要。如果这些列中的任何一列太大(例如,如果 titleTEXT),则将其关闭。否则,其中大部分是“覆盖”索引,从而提供一点额外的性能提升。

ito 列顺序对于处理 DRapp 的 ito2 很重要