今天碰到一个sql语句简化的问题,虽然也不复杂,但是也值得从中学习一些东西
SELECT MOD(((SELECT TO_NUMBER(TO_CHAR(LOGICAL_DATE, 'YYYY'))
FROM SMALL_TAB
WHERE LOGICAL_DATE_TYPE = 'R'
AND EXPIRATION_DATE IS NULL) * 365 +
(SELECT TO_NUMBER((SELECT LOGICAL_DATE
FROM SMALL_TAB
WHERE LOGICAL_DATE_TYPE = 'R'
AND EXPIRATION_DATE IS NULL) -
TRUNC(SYSDATE, 'YYYY'))
FROM DUAL)) + 1,
(SELECT NVL(PARAMETER_VALUE+1,366)FROM SMALL_TAB2
WHERE PARAMETER_NAME = 'DAY_PAR')
FROM DUAL
我得到了这样一个sql语句,但是猛一看sql语句里面包含了不少dual。
这样的sql语句是比较臃肿的,感觉需要做一些工作来改动,首先就是需要明确需求,开发想实现什么样的功能,然后在保证结果集准确的前提下来进行简化工作。
大体上沟通以后,sql语句的实现功能类似下面的形式
SELECT MOD((2014 * 365 + (165)) + 1,
366)
FROM DUAL
其实就是计算当前的年份,然后得到对应的天数和当年一月一日以来的天数。 在此基础上做计算得到一个对应的key
简单调整后,就成了下面的样子,把多余的dual全都去掉了。在测试中比较发现,对应的逻辑读一下子从128降低到了64,相应时间也有了一定的提升。
select mod(
(SELECT TO_NUMBER(TO_CHAR(LOGICAL_DATE, 'YYYY')) * 365 +
TO_NUMBER(LOGICAL_DATE - TRUNC(SYSDATE, 'YYYY')) + 1
FROM SMALL_TAB
WHERE LOGICAL_DATE_TYPE = 'R'
AND EXPIRATION_DATE IS NULL),
(SELECT NVL(PARAMETER_VALUE + 1, 366)
FROM SMALL_TAB2
WHERE PARAMETER_NAME = 'DAY_PAR')
)
from dual;
其实性能的提升不够明显,但是简单清晰的sql语句,在日常的维护中也能省不少心。