SQL SERVER 上的一个简单查询,执行时间过长

最近在生产环境中发现一条查询脚本耗时很长,排查了一天没发现问题在哪,请大神帮帮忙!

.

表结构说明:

  • SPYCDMX.MXBH、SPYCD.DJBH、YSCYD.DJBH、CANGKU.CKDM 是主键;
  • SPYCD.YS、SPYCD.YSRQ、CANGKU.XZDM、SPYCDMX.DJBH、SPYCDMX.dc_sync_flag、SPYCDMX.dc_sync_guid 是非聚集索引;
  • SPYCDMX.dc_sync_guid 字段默认值是 NULL;
  • SPYCDMX 表有400多万行数据;

.

异常查询

SELECT m.DJBH, mx.MXBH, mx.dc_sync_flag, mx.dc_sync_guid, mx.dc_sync_time
FROM SPYCDMX mx
INNER JOIN SPYCD m ON m.DJBH = mx.DJBH
LEFT JOIN CANGKU ck ON ck.CKDM = m.DM1
LEFT JOIN YSCYD cy ON cy.DJBH = m.YDJH
WHERE 1 = 1
    AND m.YS = '1'
    AND m.YSRQ >= '2019-08-16'
    AND ck.XZDM = '1'
    AND cy.DJBH IS NOT NULL
    AND mx.dc_sync_flag = 'N'
    AND mx.dc_sync_guid IS NULL

这段代码的执行时间长达3~5分钟!

.

尝试1

SELECT m.DJBH, mx.MXBH, mx.dc_sync_flag, mx.dc_sync_guid
FROM SPYCDMX mx
INNER JOIN SPYCD m ON m.DJBH = mx.DJBH
LEFT JOIN CANGKU ck ON ck.CKDM = m.DM1
LEFT JOIN YSCYD cy ON cy.DJBH = m.YDJH
WHERE 1 = 1
    AND m.YS = '1'
    AND m.YSRQ >= '2019-08-16'
    AND ck.XZDM = '1'
    AND cy.DJBH IS NOT NULL
    AND mx.dc_sync_flag = 'N'
    AND mx.dc_sync_guid IS NULL

在 SELECT 字段中剔除 mx.dc_sync_time 列,执行时间缩减到十几秒!

.

尝试2

SELECT m.DJBH, mx.MXBH, mx.dc_sync_flag, mx.dc_sync_guid
FROM SPYCDMX mx
INNER JOIN SPYCD m ON m.DJBH = mx.DJBH
LEFT JOIN CANGKU ck ON ck.CKDM = m.DM1
LEFT JOIN YSCYD cy ON cy.DJBH = m.YDJH
WHERE 1 = 1
    AND m.YS = '1'
    AND m.YSRQ >= '2019-08-16'
    AND ck.XZDM = '1'
    AND cy.DJBH IS NOT NULL
    AND mx.dc_sync_flag = 'N'
    AND ISNULL(mx.dc_sync_guid, '') = ''

把 WHERE 条件中的 AND mx.dc_sync_guid IS NULL 改为 AND ISNULL(mx.dc_sync_guid, '') = '',执行时间缩减到1~2秒!

.

这是什么原因?

sql

1个回答

mx.dc_sync_time不是索引字段,查询的时候需要进行回表查询,你把mx.MXBH去掉可能会更快,还要确定是否数据量大存在数据传输慢的问题

guangcaiwudong
Kevin.Y.K 回复刮骨剑: 你可以去看下sql的执行计划,就知道耗时在哪了,不是说用作查询条件才费时的,如果不加dc_sync_time,其他的几个字段都是索引,那返回的结果只需要从索引中返回即可,但是加了dc_sync_time ,需要先找到索引,再找到索引对应的数据行,最后组装数据返回。关联表也会sql的执行效率影响很大,不能但看表面sql,还是要看执行计划,有时候数据库引擎会选择它认为好的执行顺序。
10 个月之前 回复
zijianll
刮骨剑 dc_sync_time 虽然不是索引,但是并未用作查询条件,而仅仅是作为查询字段,不应该产生这么大的性能问题啊。另外,我有另外一条查询语句,使用了 dc_sync_time 作为条件,反而查询效率很高,真是见鬼了。另外,说到数据量的问题,同样结构(与异常查询相同)的另外一个查询,使用的明细表数据量有600多万行,但是查询结果是秒出。我怀疑是不是SPYCDMX表的索引出现问题了。
10 个月之前 回复
guangcaiwudong
Kevin.Y.K 回复刮骨剑: 那就对了,去掉了mx.dc_sync_time,全都走的索引,不用回表查询,肯定速度快乐
10 个月之前 回复
zijianll
刮骨剑 写错了,mx.MXBH 是主键
10 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐