首页 > 解决方案 > sql 查询优化 - NVL REPLACEMENT

问题描述

我正在使用 nvl 来检查一个值。如果第一条语句返回空值,则执行第二条语句。但这使查询时间增加了一倍。有更好的方法吗?

nvl(
    (
            select * from (
                    select tad.ASP_NAME  
                    from TBL_ASP_DETAILS tad 
                    where lower(te1.last_name) like '%'||lower(tad.ASSIGNED_FE_LAST_NAME)||'%'
            )
            where ROWNUM = 1
    )
    ,
    (
            select * from (
                    select tad.ASP_NAME 
                    from TBL_ASP_DETAILS tad 
                    where lower(te1.last_name) like '%'||lower(tad.ASP_NAME)||'%'
            )
            where ROWNUM = 1
    )
) ASP_NAME
,nvl(
    (
            select * from (
                    select tad.TIERING_2  
                    from TBL_ASP_DETAILS tad 
                    where lower(te1.last_name) like '%'||lower(tad.ASSIGNED_FE_LAST_NAME)||'%'
            )where ROWNUM = 1
    )
    ,
    (
            select * from (
                    select tad.TIERING_2 
                    from TBL_ASP_DETAILS tad 
                    where lower(te1.last_name) like '%'||lower(tad.ASP_NAME)||'%'
            ) where ROWNUM = 1
    )
) TIERING_2
,nvl(
    (
            select * from (
                    select tad.TIERING_1 
                    from TBL_ASP_DETAILS tad 
                    where lower(te1.last_name) like '%'||lower(tad.ASSIGNED_FE_LAST_NAME)||'%'
            )where ROWNUM = 1
    )
    ,
    (
            select * from (
                    select tad.TIERING_1 
                    from TBL_ASP_DETAILS tad 
                    where lower(te1.last_name) like '%'||lower(tad.ASP_NAME)||'%'
            )where ROWNUM = 1
    )
)TIERING_1,

标签: sqloracle

解决方案


我们只有 NVL 片段可以继续,其余的没有,我可以从 te1.last_name 参考中看到这是一个相关的子查询,因为 te1 不在上面的代码片段中。

一个粗略的想法是,您需要将 2 个查询连接在一起而不是重复它们 - 在这种情况下,基于 te1.last_name 连接,因为这似乎是您想要的,但没有其他查询可以理解上下文,我不能确定。

加入后,您可以只使用 nvl (或合并以获得更多 ANSI 方法)

性能方面,这总是会有点问题,因为您在 where 子句中使用完整的通配符搜索,以及较低的函数。

select 
    coalesce(x.asp_name, y.asp_name) as asp_name
    , coalesce(x.tiering_2, y.tiering_2) as tiering_2
    , coalesce(x.tiering_1, y.tiering_1) as tiering_1
from (

                select * from (
                        select 
                                te1.last_name, tad.ASP_NAME, tad.TIERING_2,tad.TIERING_1   
                        from TBL_ASP_DETAILS tad 
                        where lower(te1.last_name) like '%'||lower(tad.ASSIGNED_FE_LAST_NAME)||'%'
                )
                where ROWNUM = 1
) x
full join (
                select * from (
                        select te1.last_name, tad.ASP_NAME, tad.TIERING_2,tad.TIERING_1    
                        from TBL_ASP_DETAILS tad 
                        where lower(te1.last_name) like '%'||lower(tad.ASP_NAME)||'%'
                )
                where ROWNUM = 1
) y on x.last_name = y.last_name

推荐阅读