SQL中，添加一个条件后，执行效率瞬间下降，怎么优化 50C

SELECT
TR.RC_NO,
TR.FEE_TYPE,
TR.FISCAL_PERIOD,--月份
MIN (DATE_START) CUR_DATE_START,
MAX (DATE_END) CUR_DATE_END,
CONVERT(VARCHAR(30),CAST(SUM(ISNULL(FEE_ACTUAL,0))/ 10000 AS decimal(18,2)),1) AS CUR_FEE_ACTUAL,

``````replace(SUBSTRING ( CAST (DATEADD(m ,- 1,   CAST (TR.FISCAL_PERIOD + '01' AS DATE)) AS VARCHAR),1,7),'-','') AS PRE_FISCAL_PERIOD,
PRE.PRE_DATE_START,
PRE.PRE_DATE_END,
PRE.PRE_FEE_ACTUAL,

replace(SUBSTRING ( CAST (dateadd(m ,- 2,   CAST (TR.FISCAL_PERIOD + '01' AS DATE)) AS VARCHAR),1,7),'-','') AS BEF_FISCAL_PERIOD,
BEF.BEF_DATE_START,
BEF.BEF_DATE_END,
BEF.BEF_FEE_ACTUAL
``````

FROM
T_AP_PAYMENT_REQUEST TR

LEFT JOIN
(
SELECT
TP.RC_NO,TP.FEE_TYPE,
TP.FISCAL_PERIOD,
MIN (DATE_START) PRE_DATE_START,
MAX (DATE_END) PRE_DATE_END,
CONVERT(VARCHAR(30),CAST(SUM(ISNULL(FEE_ACTUAL,0))/ 10000 AS decimal(18,2)),1) AS PRE_FEE_ACTUAL
FROM
T_AP_PAYMENT_REQUEST TP
WHERE

IS_DELETE = '0'
AND IS_AUTO_PAY = 'D00002'
AND ISNULL(IS_FIRST_PAY, '') != 'D00002'
AND PR_STATUS != 'L04301'
GROUP BY
TP.RC_NO,
TP.FEE_TYPE,
TP.FISCAL_PERIOD
) PRE
ON PRE.RC_NO = TR.RC_NO AND PRE.FEE_TYPE=TR.FEE_TYPE

LEFT JOIN
(
SELECT
TA.RC_NO,TA.FEE_TYPE,
TA.FISCAL_PERIOD,
MIN (DATE_START) BEF_DATE_START,
MAX (DATE_END) BEF_DATE_END,
CONVERT(VARCHAR(30),CAST(SUM(ISNULL(FEE_ACTUAL,0))/ 10000 AS decimal(18,2)),1) AS BEF_FEE_ACTUAL
FROM
T_AP_PAYMENT_REQUEST TA
WHERE

IS_DELETE = '0'
AND IS_AUTO_PAY = 'D00002'
AND ISNULL(IS_FIRST_PAY, '') != 'D00002'
AND PR_STATUS != 'L04301'
GROUP BY
TA.RC_NO,
TA.FEE_TYPE,
TA.FISCAL_PERIOD
) BEF
ON BEF.RC_NO = TR.RC_NO AND BEF.FEE_TYPE=TR.FEE_TYPE

WHERE
TR.FISCAL_PERIOD='201701' --此语句为添加的条件
AND
PRE.FISCAL_PERIOD = replace(SUBSTRING (CAST (dateadd(m ,- 1,CAST (TR.FISCAL_PERIOD + '01' AS DATE)) AS VARCHAR),1,7),'-','')
AND BEF.FISCAL_PERIOD = replace(SUBSTRING (CAST (dateadd(m ,- 2,CAST (TR.FISCAL_PERIOD + '01' AS DATE)) AS VARCHAR),1,7),'-','')
AND TR.IS_DELETE = '0'
AND TR.IS_AUTO_PAY = 'D00002'
AND ISNULL(TR.IS_FIRST_PAY, '') != 'D00002'
AND TR.PR_STATUS != 'L04301'
GROUP BY
TR.RC_NO,
TR.FEE_TYPE,
TR.FISCAL_PERIOD,
PRE.PRE_DATE_START,
PRE.PRE_DATE_END,
PRE.PRE_FEE_ACTUAL,
BEF.BEF_DATE_START,
BEF.BEF_DATE_END,
BEF.BEF_FEE_ACTUAL
ORDER BY
TR.RC_NO,
TR.FEE_TYPE,
TR.FISCAL_PERIOD

9个回答

1、我看了下你都是查的同一张表，然后呢，我都是用等式加(+)的方式外连的，如果不支持还请自行修改

http://blog.csdn.net/fuwencaho/article/details/24672769 SQL 中的左外连接和+号的用法

2、因为语法不同，所以你写的sql我都重新翻译了一下，大概理解什么意思，有不对的地方还请自行测试

3、sql的索引我也不懂，估计都差不多，推荐你把where条件的加成索引
is_delete、is_auto_pay、is_first_pay、pr_status、fiscal_period

4、sql没办法进行测试、语法错误啥的请见谅、和PLSQL不同的函数、类似substr()、convert()、啥的我也没替换、所以可能有些怪

5、水平有限，也是写着试试，仅供参考，不对的话请及时指出，勿喷，能提供参考文献那就太感谢了

`````` SELECT tr.rc_no,
tr.fee_type,
tr.fiscal_period, --月份
MIN(tr.date_start) cur_date_start, --当月起始
MAX(tr.date_end) cur_date_end, --当月结束
convert(VARCHAR(30),
CAST(SUM(isnull(tr.fee_actual,
0)) / 10000 AS DECIMAL(18,
2)),
1) AS cur_fee_actual, --某值除1W
-1,
CAST(tr.fiscal_period + '01' AS DATE)) AS
VARCHAR),
1,
7),
'-',
'') AS pre_fiscal_period, --我看着像取上月期间
MIN(tp.date_start) pre_date_start, --上月起始
MAX(tp.date_end) pre_date_end, --上月结束
convert(VARCHAR(30),
CAST(SUM(isnull(tp.fee_actual,
0)) / 10000 AS DECIMAL(18,
2)),
1) AS pre_fee_actual, --上月某值除1W
-2,
CAST(tr.fiscal_period + '01' AS DATE)) AS
VARCHAR),
1,
7),
'-',
'') AS bef_fiscal_period, --上上月期间，感觉这段怎么好像有问题，好像不是取上上月期间
MIN(ta.date_start) bef_date_start, --上上月起始
MAX(ta.date_end) bef_date_end, --上上月结束
convert(VARCHAR(30),
CAST(SUM(isnull(ta.fee_actual,
0)) / 10000 AS DECIMAL(18,
2)),
1) AS bef_fee_actual, --上月某值除1W
FROM t_ap_payment_request tr,
t_ap_payment_request tp,
t_ap_payment_request ta
WHERE tr.rc_no = tp.rc_no(+)
AND tp.rc_no = ta.rc_no(+)
--上一期间 = tp期间
-1,
CAST(tr.fiscal_period + '01' AS DATE)) AS
VARCHAR),
1,
7),
'-',
'') = tp.fiscal_period(+)
AND tr.fee_type = tp.fee_type(+)
AND tr.is_delete = tp.is_delete(+)
AND tr.is_auto_pay = tp.is_auto_pay(+)
AND tr.is_first_pay = tp.is_first_pay(+) --注意啊，有空值字段会有BUG，请自行检查
AND tr.pr_status = tp.tr.pr_status(+)
--上两期间 = ta期间
-2,
CAST(tr.fiscal_period + '01' AS DATE)) AS
VARCHAR),
1,
7),
'-',
'') = ta.fiscal_period(+)
AND tp.fee_type = ta.fee_type(+)
AND tr.is_delete = ta.is_delete(+)
AND tr.is_auto_pay = ta.is_auto_pay(+)
AND tr.is_first_pay = ta.is_first_pay(+) --注意啊，有空值字段会有BUG，请自行检查
AND tr.pr_status = ta.tr.pr_status(+)
AND tr.is_delete = '0'
AND tr.is_auto_pay = 'D00002'
AND isnull(tr.is_first_pay,
'') != 'D00002'
AND tr.pr_status != 'L04301'
AND tr.fiscal_period = '201701' --新添加条件
GROUP BY tr.rc_no,
tr.fee_type,
tr.fiscal_period,
tr.fee_actual,
tp.fee_actual,
ta.fee_actual
``````

yu1119118430 试过这个方法了，没有优化

SqlServer中添加默认约束
SqlServer中添加默认约束 约束内容是默认值为借阅时间+1个月 借阅时间是表中的一个列

sql如下 如果不加最后一个条件and b.tzlx_dm = '00' 执行的非常快，但是如果加上之后 执行很长时间没有反应，具体的执行计划在下面，第一个没有 b.tzlx_dm = '00' 条件的（快）。 第二个有 b.tzlx_dm = '00' 条件的（慢）。 请教大神们的帮助，谢谢 SELECT nsr.nsrsbh, nsr.nsrmc, nsr.djxh, nsr.nsrzt_dm, nsr.djzclx_dm, nsr.zgswj_dm, '0' as zgxtbz FROM db_zgxt.t_dj_jgnsr a, db_zgxt.t_zs_yzmx b, dm_gy_zsxmpm d, dj_nsrxx nsr where a.nsrnbm = b.nsrnbm and a.nsrbm = nsr.nsrbm and b.zsxm_dm = d.old_dm and b.zspm_dm = d.old_dm1 and b.zf_bj = '0' and b.ykp_bj = '0' and b.yzsf_je > 0 -- and b.tzlx_dm = '00' 无 b.tzlx_dm = '00' 条件 快 ![图片说明](https://img-ask.csdn.net/upload/201705/22/1495449015_372157.jpg) 有 b.tzlx_dm = '00' 条件 慢 ![图片说明](https://img-ask.csdn.net/upload/201705/22/1495449041_22458.jpg)
SQL执行效率的问题求助

sqlServer sql语句执行后， 默认是怎么排序的

SQL2005/2008 无法执行带条件的查询

SQL语句中WHERE条件效率

oracle存储执行一段时间之后，效率变低是怎么回事

SQL如何根据传入的参数来判断是否执行where条件 存储过程
SQL如何根据传入的参数来判断是否执行where条件 存储过程怎么写的
java中如何执行原生的sql
java中如何直接执行mybatis的原生sql sql为动态，不知道具体操作的表 如何让在java代码中直接执行sql "<select id="executeSql" resultType="map"> \${sql} </select>"
VB .60条件表达式的sql server 2000数据库执行

SQL语句优化问题 执行速度太慢 ，如何优化

jdbc执行sql中日期参数问题
select 1 from dual where sysdate='2013-01-01';这样一个sql语句，在jdbc中可以正确执行，在pl/sql中确报错：“ORA-01861: literal does not match format string”,select 1 from dual where sysdate='01-1月-2013'在pl/sql中可以正常执行，求教大神，jdbc会改变我的sql语句吗？jdbc是怎么执行sql语句的？
SQL 语句优化 GROUP BY 使用 HAVING 查询非常慢，和不添加筛选条件情况相差几十倍速度
hibernate中执行原生SQL进行插入操作不起作用,sql在数据库中能正常执行
hibernate中执行原生SQL进行插入操作createSQLQuery(sql).executeUpdate，不起作用,sql在数据库中能正常执行，事务是使用spring配置文件做的，类中有@Transactional注解，各位前辈是否遇到过同样问题，望指教！

SQL文件乱码如何解决 执行不了

《奇巧淫技》系列-python！！每天早上八点自动发送天气预报邮件到QQ邮箱

8年经验面试官详解 Java 面试秘诀

MyBatis研习录(01)——MyBatis概述与入门
MyBatis 是一款优秀的持久层框架，它支持定制化 SQL、存储过程以及高级映射。MyBatis原本是apache的一个开源项目iBatis, 2010年该项目由apache software foundation 迁移到了google code并改名为MyBatis 。2013年11月MyBatis又迁移到Github。

Python爬虫爬取淘宝，京东商品信息

Java工作4年来应聘要16K最后没要,细节如下。。。

Python爬虫精简步骤1 获取数据

Python绘图，圣诞树，花，爱心 | Turtle篇

CPU对每个程序员来说，是个既熟悉又陌生的东西？ 如果你只知道CPU是中央处理器的话，那可能对你并没有什么用，那么作为程序员的我们，必须要搞懂的就是CPU这家伙是如何运行的，尤其要搞懂它里面的寄存器是怎么一回事，因为这将让你从底层明白程序的运行机制。 随我一起，来好好认识下CPU这货吧 把CPU掰开来看 对于CPU来说，我们首先就要搞明白它是怎么回事，也就是它的内部构造，当然，CPU那么牛的一个东...

web前端javascript+jquery知识点总结
1.Javascript 语法.用途 javascript 在前端网页中占有非常重要的地位，可以用于验证表单，制作特效等功能，它是一种描述语言，也是一种基于对象（Object）和事件驱动并具有安全性的脚本语言 ...
Python实战：抓肺炎疫情实时数据，画2019-nCoV疫情地图

Python：爬取疫情每日数据

B 站上有哪些很好的学习资源?

Web播放器解决了在手机浏览器和PC浏览器上播放音视频数据的问题，让视音频内容可以不依赖用户安装App，就能进行播放以及在社交平台进行传播。在视频业务大数据平台中，播放数据的统计分析非常重要，所以Web播放器在使用过程中，需要对其内部的数据进行收集并上报至服务端，此时，就需要对发生在其内部的一些播放行为进行事件监听。 那么Web播放器事件监听是怎么实现的呢？ 01 监听事件明细表 名...
3万字总结，Mysql优化之精髓

Python新型冠状病毒疫情数据自动爬取+统计+发送报告+数据屏幕（三）发送篇

1.Matlab实现粒子群算法的程序代码：https://www.cnblogs.com/kexinxin/p/9858664.html matlab代码求解函数最优值：https://blog.csdn.net/zyqblog/article/details/80829043 讲解通俗易懂，有数学实例的博文：https://blog.csdn.net/daaikuaichuan/article/...

1. 传统事件绑定和符合W3C标准的事件绑定有什么区别？ 传统事件绑定 &lt;div onclick=""&gt;123&lt;/div&gt; div1.onclick = function(){}; &lt;button onmouseover=""&gt;&lt;/button&gt; 注意： 如果给同一个元素绑定了两次或多次相同类型的事件，那么后面的绑定会覆盖前面的绑定 （不支持DOM事...