场景:
需要获取部分数据集(视图)的业务时间最大值,希望只通过一条语句获取多个的最大值。
则使用select (视图1业务时间最大值),(视图2业务时间最大值),(视图3业务时间最大值) from dual
程序执行过程中,发现语句执行较慢,则进行sql调优。
使用子方式查询,获取最大值
子查询是一个嵌套在另一个查询语句中的查询语句。它可以被视为一个查询被包含在另一个查询中的过滤条件,可以在查询语句中的WHERE,FROM或SELECT子句中使用。子查询可以返回单个值、单个行或多个行,并且可以被用来解决复杂性问题或减少查询中的代码复杂性。
select (SELECT max(SJGXSJ) TIME_MAX
FROM v_yewu1
where SJGXSJ >= sysdate - 1
and SJGXSJ < sysdate) AS TIME1,
NULL AS TIME2,
NULL AS TIME3,
NULL AS TIME4,
NULL AS TIME5
from dual
where 1 = 1
如图,效果很不理想。
如果是拿子查询的语句出来,单独查询,就会走时间索引,就很快。
使用union方式查询,获取最大值
改成union空表
union是合并两个查询的,怎么也会导致执行计划发生改变呢,第一时间想到的是union中去重导致的。然后我吧union 改成union all结果,执行计划还是很糟糕。
使用join方式查询,获取最大值
最后,把语句改成关联的形式,总算是满足了实际的业务需要。
select t1.TIME_MAX AS TIME1,
t2.TIME_MAX AS TIME2,
NULL AS TIME3,
NULL AS TIME4,
NULL AS TIME5
from (SELECT max(SJGXSJ) TIME_MAX
FROM v_yuwu1
where SJGXSJ >= sysdate - 1
and SJGXSJ < sysdate) t1,
(SELECT max(SJGXSJ) TIME_MAX
FROM v_yuwu2
where SJGXSJ >= sysdate - 1
and SJGXSJ < sysdate) t2a
where 1 = 1
总结
sql执行过程中,视图查询,使用子查询、union或者多层视图嵌套,都可能会导致执行计划发生改变,多层视图嵌套结构的语句,where条件位置等都有可能导致执行计划发生改变,索引不生效的问题,这些应当尽量避免。sql调优过程中也可以使用些hint进行优化。使用视图查询,还是有明显的劣势,条件允许,尽量使用直接的sql语句查询,并且避免sql里面用到视图。