多表连接SQL查询执行速度慢 如何优化语句提升运行性能

SQL慢查询优化方案
你这条查询慢的核心问题集中在关联逻辑错误、过滤条件冗余、索引缺失三个方面,按以下步骤调整即可大幅降低执行耗时:
现存核心问题
- 关联条件缺失导致笛卡尔积:关联
SALESLINE表时仅用了销售单IDORIGSALESID=SALESID关联,没有绑定行级标识INVENTTRANSID,单张销售单下通常有多条销售行,这会导致1条发票行和该单下所有销售行做交叉连接,数据量呈倍数膨胀,是耗时高的最主要原因。 - 过滤条件重复冗余:针对主表的时间过滤条件
CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())在每个JOIN子句中重复书写,不会提升过滤效率,反而会干扰查询优化器的执行计划生成。 - 无匹配索引支撑:关联键、过滤键没有对应覆盖索引时,数据库会对大表做全表扫描,产生大量不必要的IO开销。
具体优化步骤
- 修正SQL逻辑,补全关联条件、收拢过滤位置,改写后SQL如下:
SELECT CUSTINVOICETRANS.INVENTTRANSID, CUSTINVOICETRANS.INVOICEDATE, CUSTINVOICETRANS.INVOICEID, CUSTINVOICETRANS.ITEMID, CUSTINVOICETRANS.LINEAMOUNT, CUSTINVOICETRANS.LINEAMOUNTTAX, CUSTINVOICETRANS.ORIGSALESID, CUSTINVOICETRANS.QTY, CUSTINVOICETRANS.SUMLINEDISC, CUSTINVOICEJOUR.CUSTGROUP, CUSTINVOICEJOUR.INVOICEACCOUNT, CUSTINVOICEJOUR.SALESID, SALESTABLE.VCORDERMODE, SALESTABLE.VCORDERRT, VCSALESTABLEINFO.RCVDATE, VCSALESTABLEINFO.SHPCSTMCD, VCSALESTABLEINFO.VCORIGINALINVOICEDATE, SALESLINE.DATAAREADID, SALESLINE.INVENTTRANSID, VCSALESLINEINFO.RLLINEID FROM CUSTINVOICETRANS INNER JOIN CUSTINVOICEJOUR ON CUSTINVOICETRANS.INVOICEID = CUSTINVOICEJOUR.INVOICEID AND CUSTINVOICETRANS.INVOICEDATE = CUSTINVOICEJOUR.INVOICEDATE INNER JOIN SALESTABLE ON CUSTINVOICETRANS.ORIGSALESID = SALESTABLE.SALESID INNER JOIN VCSALESTABLEINFO ON CUSTINVOICETRANS.ORIGSALESID = VCSALESTABLEINFO.SALESID INNER JOIN SALESLINE ON CUSTINVOICETRANS.ORIGSALESID = SALESLINE.SALESID AND CUSTINVOICETRANS.INVENTTRANSID = SALESLINE.INVENTTRANSID -- 补全行级关联,避免笛卡尔积 INNER JOIN VCSALESLINEINFO ON SALESLINE.INVENTTRANSID = VCSALESLINEINFO.INVENTTRANSID WHERE CUSTINVOICETRANS.INVOICEDATE >= DATEADD(DAY,-7,GETDATE()) -- 统一过滤主表近7天数据,提前缩小数据集
- 创建匹配的覆盖索引,避免全表扫描和回表查询(从语法判断你用的是SQL Server,按以下规则建索引即可):
CUSTINVOICETRANS表:索引键设为INVOICEDATE, INVOICEID, ORIGSALESID, INVENTTRANSID,包含列添加ITEMID, LINEAMOUNT, LINEAMOUNTTAX, QTY, SUMLINEDISC,可以直接从索引取出主表需要的所有近7天数据,无需回表。CUSTINVOICEJOUR表:索引键设为INVOICEID, INVOICEDATE,包含列添加CUSTGROUP, INVOICEACCOUNT, SALESIDSALESTABLE表:索引键设为SALESID,包含列添加VCORDERMODE, VCORDERRTVCSALESTABLEINFO表:索引键设为SALESID,包含列添加RCVDATE, SHPCSTMCD, VCORIGINALINVOICEDATESALESLINE表:索引键设为SALESID, INVENTTRANSID,包含列添加DATAAREADIDVCSALESLINEINFO表:索引键设为INVENTTRANSID,包含列添加RLLINEID
- 执行计划校验:调整后查看实际执行计划,确认不存在大表全扫描、键查找、关联后行数异常膨胀的问题即可。
额外注意:如果你的业务中
INVOICEID是按数据区域(公司/账套)维度唯一,记得在CUSTINVOICETRANS和CUSTINVOICEJOUR的关联条件中补上对应数据区域字段(比如常见的DATAAREADID)的等值判断,避免跨账套关联出脏数据。
内容的提问来源于stack exchange,提问作者GabrielP
相关产品推荐
相关产品推荐

