Sql 查询的性能调优

Sql 查询的性能调优,sql,sql-server,query-performance,Sql,Sql Server,Query Performance,我有一个需要很长时间才能运行的查询。这可能是因为我在连接条件中使用了太多的isnull。如何通过删除isnull来优化它 是否有其他方法不更新表?查询如下: select pos.C_id ,pos.s_id ,pos.A_id ,pos.Ad_id ,pos.Pr_id ,pos.prog_id ,pos.port_id ,pos.o_type ,pos.o_id ,pos.s_id ,pos.c_id

我有一个需要很长时间才能运行的查询。这可能是因为我在连接条件中使用了太多的
isnull
。如何通过删除
isnull
来优化它

是否有其他方法不更新表?查询如下:

 select pos.C_id
    ,pos.s_id
    ,pos.A_id
    ,pos.Ad_id
    ,pos.Pr_id
    ,pos.prog_id
    ,pos.port_id
    ,pos.o_type
    ,pos.o_id
    ,pos.s_id
    ,pos.c_id
    ,pos.s_type_id
    ,pos.s_type
    ,pos.e_date
    ,pos.mv
    ,0 is_pub
    , 1 is_adj           
    ,pos.is_unsup
    ,getdate() date
    ,getdate() timestamp
    from #temp pos
    left join acc c with(nolock) ON pos._id = c.c_id
    AND pos.account_id = c.account_id
    AND isnull(pos.Pr_id,0) = isnull(c.pr_id,0)
    AND isnull(pos.prog_id,0) = isnull(c.prog_id,0)
    AND isnull(pos.port_id,0) = isnull(c.port_id,0)
    and isnull(pos.style_type_id,0)=isnull(c.s_type_id,0)
    AND pos.s_id = c._id
    AND pos.c_id = c.c_id
    AND pos.s_type = c.s_type
    AND pos.is_unsup = c.is_uns
    AND pos.is_pub = 1
    where c.a_id is null
试用

AND (pos.Pr_id = c.pr_id OR (pos.Pr_id IS NULL AND c.pr_id IS NULL))
而不是

AND ISNULL(pos.Pr_id,0) = ISNULL(c.pr_id,0)

IS NULL比ISNULL效率更高

您确实需要在临时表上设置聚集索引
#temp
,如果不存在,sql server将为联接提供默认的基于哈希的索引,而对于大型表则不起作用

如果
#temp
表中的所有id列中的任何一列是唯一键,则确实需要在其上创建聚集索引:

CREATE CLUSTERED INDEX cx_temp ON #temp (YourIDColumn);
如果在
#temp
中没有键列,请通过以下方式向其添加标识主键:

1) 如果您使用
选择进入
方法来创建
#临时
,请更改

select *
into #temp
from YourQuery

1) 如果使用
CREATE TABLE
+
INSERT-INTO
方法,只需添加如下列:

CREATE TABLE #TEMP (
    ThisIsTheKey INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    ..
    ..
    -- ALL YOUR OTHER COLUMNS
    ..
    ..
)
不要依赖于覆盖非聚集索引,因为优化器可能不会使用它们,因为您选择的列太多


首先测试聚集索引,然后如果需要进一步优化,可以尝试添加一些特定的非聚集索引。

下面的查询如何

 select pos.C_id
    ,pos.s_id
    ,pos.A_id
    ,pos.Ad_id
    ,pos.Pr_id
    ,pos.prog_id
    ,pos.port_id
    ,pos.o_type
    ,pos.o_id
    ,pos.s_id
    ,pos.c_id
    ,pos.s_type_id
    ,pos.s_type
    ,pos.e_date
    ,pos.mv
    ,0 is_pub
    , 1 is_adj           
    ,pos.is_unsup
    ,getdate() date
    ,getdate() timestamp
    from #temp pos
    left join acc c with(nolock) ON pos._id = c.c_id
    AND pos.account_id = c.account_id
    AND pos.Pr_id = c.pr_id
    AND pos.prog_id = c.prog_id
    AND pos.port_id = c.port_id
    and pos.style_type_id=c.s_type_id
    AND pos.s_id = c._id
    AND pos.c_id = c.c_id
    AND pos.s_type = c.s_type
    AND pos.is_unsup = c.is_uns
    AND pos.is_pub = 1
    where c.a_id is null
union all
 select pos.C_id
    ,pos.s_id
    ,pos.A_id
    ,pos.Ad_id
    ,pos.Pr_id
    ,pos.prog_id
    ,pos.port_id
    ,pos.o_type
    ,pos.o_id
    ,pos.s_id
    ,pos.c_id
    ,pos.s_type_id
    ,pos.s_type
    ,pos.e_date
    ,pos.mv
    ,0 is_pub
    , 1 is_adj           
    ,pos.is_unsup
    ,getdate() date
    ,getdate() timestamp
    from #temp pos
    left join acc c with(nolock) ON pos._id = c.c_id
    AND pos.account_id = c.account_id
    AND pos.s_id = c._id
    AND pos.c_id = c.c_id
    AND pos.s_type = c.s_type
    AND pos.is_unsup = c.is_uns
    AND pos.is_pub = 1
    where c.a_id is null
    AND pos.Pr_id is null AND  c.pr_id is null
    AND pos.prog_id is null AND  c.prog_id is null
    AND pos.port_id is null AND  c.port_id is null
    and pos.style_type_id is null AND c.s_type_id is null

检查您的执行计划及其建议。可能正在创建一个覆盖索引,这对您的情况可能会有所帮助
 select pos.C_id
    ,pos.s_id
    ,pos.A_id
    ,pos.Ad_id
    ,pos.Pr_id
    ,pos.prog_id
    ,pos.port_id
    ,pos.o_type
    ,pos.o_id
    ,pos.s_id
    ,pos.c_id
    ,pos.s_type_id
    ,pos.s_type
    ,pos.e_date
    ,pos.mv
    ,0 is_pub
    , 1 is_adj           
    ,pos.is_unsup
    ,getdate() date
    ,getdate() timestamp
    from #temp pos
    left join acc c with(nolock) ON pos._id = c.c_id
    AND pos.account_id = c.account_id
    AND pos.Pr_id = c.pr_id
    AND pos.prog_id = c.prog_id
    AND pos.port_id = c.port_id
    and pos.style_type_id=c.s_type_id
    AND pos.s_id = c._id
    AND pos.c_id = c.c_id
    AND pos.s_type = c.s_type
    AND pos.is_unsup = c.is_uns
    AND pos.is_pub = 1
    where c.a_id is null
union all
 select pos.C_id
    ,pos.s_id
    ,pos.A_id
    ,pos.Ad_id
    ,pos.Pr_id
    ,pos.prog_id
    ,pos.port_id
    ,pos.o_type
    ,pos.o_id
    ,pos.s_id
    ,pos.c_id
    ,pos.s_type_id
    ,pos.s_type
    ,pos.e_date
    ,pos.mv
    ,0 is_pub
    , 1 is_adj           
    ,pos.is_unsup
    ,getdate() date
    ,getdate() timestamp
    from #temp pos
    left join acc c with(nolock) ON pos._id = c.c_id
    AND pos.account_id = c.account_id
    AND pos.s_id = c._id
    AND pos.c_id = c.c_id
    AND pos.s_type = c.s_type
    AND pos.is_unsup = c.is_uns
    AND pos.is_pub = 1
    where c.a_id is null
    AND pos.Pr_id is null AND  c.pr_id is null
    AND pos.prog_id is null AND  c.prog_id is null
    AND pos.port_id is null AND  c.port_id is null
    and pos.style_type_id is null AND c.s_type_id is null