VerySource

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2966|回复: 17

[请教] 查询效率问题 (当查询条件in和and 同时存在的时候查询效率为啥巨低?),非常感谢

[复制链接]

1

主题

6

帖子

5.00

积分

新手上路

Rank: 1

积分
5.00
发表于 2020-3-21 12:00:01 | 显示全部楼层 |阅读模式

1.SELECT * FROM ....
WHERE NAME IN ('NAME1')

2.SELECT * FROM ....
WHERE AGET= 3

3.SELECT * FROM ....
WHERE NAME IN ('NAME1') AND AGET= 3


1和2的效率差不多多.但3却需要1的40倍时间来查询,为什么会这样????

真实语句如下:

SELECT     dbo.USER_INFO.USER_NAME, dbo.SCR_FORM.SCR_FORM_ID, dbo.SCR_FORM.SCR_FORM_CODE, dbo.SCR_FORM.PRJ_CONTRACT_CD,   
                      dbo.SCR_FORM.SC_TYPE, dbo.SCR_FORM.SC_FRAME, dbo.SCR_FORM.OS_VENDOR_CODE, dbo.SCR_FORM.OS_TEAM_CODE,   
                      dbo.SCR_FORM.SUBMIT_DATE, dbo.SCR_FORM.STATUS, dbo.SCR_FORM.SUBMITTER_USER_CD, dbo.SCR_FORM.BGM_USER_CD,   
                      dbo.SCR_FORM.CPM_USER_CD, dbo.SCR_FORM.CPD_USER_CD, dbo.SCR_FORM.OS_USER_CD, dbo.OS_VENDOR.FULL_NAME AS VENDORNAME,   
                      dbo.OS_TEAM.FULL_NAME AS TEAMNAME, dbo.PROJECT.PROJECT_NAME, dbo.PROJECT.PARTY_ID  
FROM         dbo.SCR_FORM INNER JOIN  
                      dbo.PROJECT ON dbo.SCR_FORM.PRJ_CONTRACT_CD = dbo.PROJECT.PROJECT_CD LEFT OUTER JOIN  
                      dbo.USER_INFO ON dbo.SCR_FORM.SUBMITTER_USER_CD = dbo.USER_INFO.USER_CD LEFT OUTER JOIN  
                      dbo.OS_TEAM ON dbo.SCR_FORM.OS_TEAM_CODE = dbo.OS_TEAM.OS_TEAM_CODE LEFT OUTER JOIN  
                      dbo.OS_VENDOR ON dbo.SCR_FORM.OS_VENDOR_CODE = dbo.OS_VENDOR.OS_VENDOR_CODE  
                          --下面是in条件
                        where SCR_FORM.SCR_FORM_CODE in
                        (SELECT              
                                                 distinct SC_ITEM.SCR_FORM_CODE
                                                 FROM     dbo.SC_ITEM
                                                INNER JOIN
                                                dbo.EI_ORDER_ITEM   on EI_ORDER_ITEM.TASK_ID  =SC_ITEM.task_id INNER JOIN
                                                 dbo.PRODUCT_LINE ON dbo.EI_ORDER_ITEM.PRODUCT_LINE = dbo.PRODUCT_LINE.PRODUCT_LINE_CD
                                       
                        where SC_ITEM.STATUS='APPROVED' --and SC_ITEM.SCR_FORM_CODE is not null
                        and  (product_line.product_type_cd<>'adsl' and product_line.product_type_cd<>'s12'))
--下面是AND条件
and SCR_FORM.prj_contract_cd = 'cr050053r-0640'
回复

使用道具 举报

0

主题

35

帖子

22.00

积分

新手上路

Rank: 1

积分
22.00
发表于 2020-6-27 10:45:01 | 显示全部楼层
CTRL + L 看一下。
回复

使用道具 举报

0

主题

126

帖子

73.00

积分

新手上路

Rank: 1

积分
73.00
发表于 2020-6-28 22:30:02 | 显示全部楼层
只能自己通过执行计划看看哪个地方耗资源了。。

大家没数据,不好诊断

in条件中那几个inner join 是不是可以优化?
还有子查询中的DISTINCT..
回复

使用道具 举报

0

主题

9

帖子

7.00

积分

新手上路

Rank: 1

积分
7.00
发表于 2020-6-29 00:45:01 | 显示全部楼层
楼主的意思是去掉其中一个条件, 速度就快很多了?

那么可能的原因是sql没有使用正确的执行计划.

尝试用下面的方法来解决:
1. 查询分析器连接到你的实例, 输入你的语句, 按Ctrl+L查看执行计划, 重点检查执行计划中, 有没有红色标注的结点, 如果有, 说明是统计信息丢失, 一般在红色标注的地方按右键--创建丢失的统计就可以解决.

2. 如果确实不是统计信息丢失, 同样用Ctrl+L的方法, 比较,同时应用条件和只加一个条件时, 执行计划的差异(重点在于使用的索引)
   绝大部分情况下, SQL会选择正确的索引, 但有时会选择错误, 这种情况下, 你可以通过强制指定索引的方法来解决(根据Ctrl+L分析的结果确定如何走索引是最有效的)
回复

使用道具 举报

0

主题

211

帖子

108.00

积分

新手上路

Rank: 1

积分
108.00
发表于 2020-6-29 09:30:01 | 显示全部楼层
用EXISTS作判断试试
回复

使用道具 举报

0

主题

16

帖子

10.00

积分

新手上路

Rank: 1

积分
10.00
发表于 2020-7-3 17:45:01 | 显示全部楼层
单独看看子查询的性能:

(SELECT              
distinct SC_ITEM.SCR_FORM_CODE
FROM     dbo.SC_ITEM
INNER JOIN
dbo.EI_ORDER_ITEM   on EI_ORDER_ITEM.TASK_ID  =SC_ITEM.task_id INNER JOIN
dbo.PRODUCT_LINE ON dbo.EI_ORDER_ITEM.PRODUCT_LINE = dbo.PRODUCT_LINE.PRODUCT_LINE_CD

where SC_ITEM.STATUS='APPROVED' --and SC_ITEM.SCR_FORM_CODE is not null
and  (product_line.product_type_cd<>'adsl' and product_line.product_type_cd<>'s12'))
回复

使用道具 举报

0

主题

34

帖子

17.00

积分

新手上路

Rank: 1

积分
17.00
发表于 2020-7-9 20:15:01 | 显示全部楼层
难道是这两个条件同时用时索引破坏?
回复

使用道具 举报

0

主题

114

帖子

69.00

积分

新手上路

Rank: 1

积分
69.00
发表于 2020-7-9 21:45:01 | 显示全部楼层
try:
SELECT * FROM (select * from ... where adet=3)a
WHERE NAME IN ('NAME1')
回复

使用道具 举报

0

主题

1

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-7-22 21:30:01 | 显示全部楼层
不是有测试工具可以检测的么
回复

使用道具 举报

1

主题

6

帖子

5.00

积分

新手上路

Rank: 1

积分
5.00
 楼主| 发表于 2020-7-23 20:30:01 | 显示全部楼层
首先谢谢各位的热心回答!回复如下:

楼主的意思是去掉其中一个条件, 速度就快很多了?

---是的.子查询性能2秒.; 使用in后的总查询是1苗;使用SCR_FORM.prj_contract_cd = 'cr050053r-0640'后的总查询是不足1秒;使用in并且用SCR_FORM.prj_contract_cd = 'cr050053r-0640'后的总查询是88秒!

尝试用下面的方法来解决:
1. 查询分析器连接到你的实例, 输入你的语句, 按Ctrl+L查看执行计划, 重点检查执行计划中, 有没有红色标注的结点, 如果有, 说明是统计信息丢失, 一般在红色标注的地方按右键--创建丢失的统计就可以解决.

--没有错误

2. 如果确实不是统计信息丢失, 同样用Ctrl+L的方法, 比较,同时应用条件和只加一个条件时, 执行计划的差异(重点在于使用的索引)
   绝大部分情况下, SQL会选择正确的索引, 但有时会选择错误, 这种情况下, 你可以通过强制指定索引的方法来解决(根据Ctrl+L分析的结果确定如何走索引是最有效的)

--分析后的结果看得不是很清楚(各模块所占的百分比是挺平均的).


用EXISTS作判断试试
---测试过了,效果没有变化.


单独看看子查询的性能:

(SELECT              
distinct SC_ITEM.SCR_FORM_CODE
FROM     dbo.SC_ITEM
INNER JOIN
dbo.EI_ORDER_ITEM   on EI_ORDER_ITEM.TASK_ID  =SC_ITEM.task_id INNER JOIN
dbo.PRODUCT_LINE ON dbo.EI_ORDER_ITEM.PRODUCT_LINE = dbo.PRODUCT_LINE.PRODUCT_LINE_CD

where SC_ITEM.STATUS='APPROVED' --and SC_ITEM.SCR_FORM_CODE is not null
and  (product_line.product_type_cd<>'adsl' and product_line.product_type_cd<>'s12'))

--子查询性能2秒.; 使用in后的总查询是1苗;使用SCR_FORM.prj_contract_cd = 'cr050053r-0640'后的总查询是不足1秒;使用in并且用SCR_FORM.prj_contract_cd = 'cr050053r-0640'后的总查询是88秒!

难道是这两个条件同时用时索引破坏?
--不明白什么意思....

try:
SELECT * FROM (select * from ... where adet=3)a
WHERE NAME IN ('NAME1')

--这个早测试过了,没有效果.

不是有测试工具可以检测的么
--啥测试工具?

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

快速回复 返回顶部 返回列表