Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查询中的多个联接_Sql_Sql Server_Join_Query Optimization - Fatal编程技术网

Sql 查询中的多个联接

Sql 查询中的多个联接,sql,sql-server,join,query-optimization,Sql,Sql Server,Join,Query Optimization,我有一个SP,涉及超过10个表。在带下划线的行中,有一个表AllData,由于where子句中的字段名,它被联接了3次 任何关于如何更好地处理这个复杂查询的建议都将不胜感激。通常,为了避免多次加入AllData(别名为ad1、adl2、adl3)。这可能会影响性能 这是sp ALTER PROCEDURE [dbo].[StoredProc1] AS select case when pd.Show_Photo = '1,1,1' then i.id

我有一个SP,涉及超过10个表。在带下划线的行中,有一个表AllData,由于where子句中的字段名,它被联接了3次

任何关于如何更好地处理这个复杂查询的建议都将不胜感激。通常,为了避免多次加入AllData(别名为ad1、adl2、adl3)。这可能会影响性能

这是sp

ALTER PROCEDURE [dbo].[StoredProc1]
AS
select  case when pd.Show_Photo = '1,1,1'
             then i.id
             else null
        end as thumbimage,
        t1.FPId,
        'WebProfile' as profiletype,
        mmbp.Name as Name,
        t1.Age,
        t1.Height,
        adl.ListValue as AlldataValue1,
        adl2.ListValue as AlldataValue2,
        adl3.ListValue as AlldataValue3,
        c.CName,
        ed.ELevel,
        ed.EDeg,
        NEWID()
from Table2  mmbp, Table3  u
join Table1 t1 on t1.Pid = u.Pid
left join Table4 mmb on t1.Pid= mmb.Pid 
join table5 i on t1.Pid = i.Pid 
join table6 pd on t1.Pid = pd.Pid
join table7 ed on t1.Pid = ed.Pid
join table8 c on t1.xxx= c.xxx
join AllData  adl on t1.xxx = adl.ListKey 
join AllData adl2 on b.ms = adl2.ListKey
join AllData adl3 on b.Diet = adl3.ListKey
where adl.FieldName=xxx and
      adl2.FieldName='ms' and
      adl3.FieldName='Diet' and 
      ------ 

可以尝试的一件事是将where条件移动到连接中

join AllData ad1 on t1.xxx = ad1.ListKey AND ad1.FieldName = xxx
join AllData ad2 on b.ms = adl2.ListKey AND ad2.FieldName = 'ms'
join AllData ad3 on b.Diet = adl3.ListKey AND ad3.FieldName = 'Diet'

这将提供更好的性能,因为联接大小将仅限于所需的记录。要做到这一点,您可以
在(t1.xxx=ad.ListKey和ad.FieldName=xxx)或(b.ms=ad.ListKey和ad.FieldName='ms')…
上加入所有数据ad。此选项的问题是,ad1、ad2等不再具有不同的列。

我注意到,表2和表3之间似乎存在笛卡尔连接-除非其中一个表非常小,否则这可能会严重影响性能。我建议显式地将表2连接到查询中的其他表之一,以提高性能。

“这将提供更好的性能,因为连接大小将仅限于您想要的记录”-将谓词从where子句移动到join子句不会影响生成的执行计划(在本例中为内部连接)-试试看yourself@JCooper:“不太可能影响生成的执行计划”比“不会影响生成的执行计划”更好,除非您自己编写了SQLServer优化器,并且知道它在任何可能的情况下都会做什么?(考虑到OP没有包含整个查询…@markbannister-事实上,我没有编写优化器。关键是,从逻辑上讲,它们是同一个查询。对于内部联接,联接条件是在联接谓词中指定的,还是在where子句中指定的,并且在逻辑上是相同的,这无关紧要。只有在指定联接条件的位置,左联接才有意义。话虽如此,它们在逻辑上是完全相同的,我想说,优化器生成两个不同的计划的可能性很小。@Mark Bannister-只是好奇,你指出“OP没有包含整个查询”。您是否知道会导致优化器生成不同计划的场景?@JCooper:从逻辑上讲,你是对的,但我知道优化器的行为方式是不可预料的。在
where
子句中省略的条件中,Table2(别名mmbp)和任何其他表之间是否存在连接条件?另外,运行查询时是否可以包括查询的其余部分和查询计划?