SQL select字段导致主要性能问题

时间:2011-06-23 20:19:41

标签: sql performance sql-server-2005 sql-execution-plan

我有一个存储过程,它连接在许多表中并从中选择字段。其中一个表是临时表。

SELECT
    a.Field1,
    a.Field2,
    b.Field3,
    b.Field4,
    c.Field5
FROM table1 a
    LEFT JOIN #table2 b ON a.Field1 = b.Field1
    INNER JOIN table3 c ON a.Field1 = c.Field1

上述情况需要10分钟以上,但是如果我将select中的两个b字段注释掉,同时将连接保留在原位,则只需几秒钟即可运行。

我已将此程序撤出以简化和相同的行为。执行计划几乎完全相同。

感谢任何帮助。

5 个答案:

答案 0 :(得分:1)

您是否尝试过反转连接? (尽管您在示例查询中缺少表c的连接条件)

SELECT
    a.Field1,
    a.Field2,
    b.Field3,
    b.Field4,
    c.Field5
FROM table1 a
    INNER JOIN table3 c
    LEFT JOIN #table2 b ON a.Field1 = b.Field1

答案 1 :(得分:1)

临时表中有多少行,临时表中的“Field2”是主键?

如果您没有从左连接的右表中选择任何行,并且连接是主键(或可能是唯一键),并且您没有引用右表中的列,则SQL Server可以避免根本不必访问临时表(因为连接行的存在与否对最终结果没有影响):

实施例。表格设置:

create table T1 (
    ID int not null primary key,
    Col1 varchar(10) not null
)
go
insert into T1 (ID,Col1)
select 1,'a' union all
select 2,'b' union all
select 3,'c'
go
create table #t2 (
    ID int not null primary key,
    Col2 varchar(10) not null
)
go
insert into #t2 (ID,Col2)
select 1,'d' union all
select 2,'e' union all
select 4,'f'
go
create table #t3 (
    ID int not null,
    Col3 varchar(10) not null
)
go
insert into #t3 (ID,Col3)
select 1,'d' union all
select 2,'e' union all
select 1,'f'

查询:

select T1.ID,T1.Col1 from T1 left join #t2 t2 on T1.ID = t2.ID
select T1.ID,T1.Col1,t2.Col2 from T1 left join #t2 t2 on T1.ID = t2.ID
select T1.ID,T1.Col1 from T1 left join #t3 t3 on T1.ID = t3.ID
select T1.ID,T1.Col1,t3.Col2 from T1 left join #t2 t3 on T1.ID = t3.ID

除第一个查询外,其他所有查询都按预期进行连接。但是因为#t2中存在或不存在行不会影响第一个查询的最终结果,所以它可以避免完全执行连接。

但是,如果它不是那样的(并且我希望它在查询计划中是明显的差异)<我有点难过。

答案 2 :(得分:0)

我会尝试将包含列的索引添加到#table2,看看是否有帮助:

CREATE NONCLUSTERED INDEX IX_table2
    ON #table2 (Field1)
    INCLUDE (Field3, Field4);

答案 3 :(得分:0)

如何分两部分运行查询。使第一部分尽可能具有限制性,然后仅在过滤集上进行外连接。

SELECT    a.Field1,   
          a.Field2,    
          b.Field3,       
          c.Field5
INTO #t
FROM table1 a   
    INNER JOIN table3 c ON a.Field1 = c.Field1

SELECT t.Field1,
       t.field2,
       b.field3,
       b.field4,
       t.field5
FROM #t t
     LEFT OUTER JOIN #table2 b ON t.Field1 = b.Field1            

答案 4 :(得分:0)

select * into #temp from table1
select * into #temp1 from table2
select * into #temp2 from table3


SELECT
    a.Field1,
    a.Field2,
    b.Field3,
    b.Field4,
    c.Field5
FROM #temp a
    LEFT JOIN #temp1 b ON a.Field1 = b.Field1
    INNER JOIN #temp2 c ON a.Field1 = c.Field1



if(Object_Id('TempDB..#temp') Is Not Null)
Begin
    Drop table #temp
End
if(Object_Id('TempDB..#temp1') Is Not Null)
Begin
    Drop table #temp1
End
if(Object_Id('TempDB..#temp2') Is Not Null)
Begin
    Drop table #temp2
End