Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.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_Tsql_Stored Procedures_Database Performance_Sql Execution Plan - Fatal编程技术网

Sql 比这更有效的工会声明?

Sql 比这更有效的工会声明?,sql,tsql,stored-procedures,database-performance,sql-execution-plan,Sql,Tsql,Stored Procedures,Database Performance,Sql Execution Plan,我正在尝试连接一些通用的搜索结果,并希望它能够像我可能做到的那样执行。现在并不可怕,但我觉得我有可能改进其中的“where”部分,甚至可以将其浓缩为一个where子句。我还担心随着时间的推移,随着数据库的增长,这将如何执行 我的问题是,是否有更好的方法将这些信息连接在一起(当我们基本上重复使用相似的表子集时,这是UNIONALL的替代方法)。所有这些都有很好的索引,执行计划显示大部分成本分布相当均匀 Select Distinct m.MLSDataId as ResultId, m.MLSNu

我正在尝试连接一些通用的搜索结果,并希望它能够像我可能做到的那样执行。现在并不可怕,但我觉得我有可能改进其中的“where”部分,甚至可以将其浓缩为一个where子句。我还担心随着时间的推移,随着数据库的增长,这将如何执行

我的问题是,是否有更好的方法将这些信息连接在一起(当我们基本上重复使用相似的表子集时,这是UNIONALL的替代方法)。所有这些都有很好的索引,执行计划显示大部分成本分布相当均匀

Select Distinct m.MLSDataId as ResultId, m.MLSNumber as ResultName, '#/mlsrecord/'+convert(varchar(20),m.MLSDataId) as ResultLink, a.StreetLine1 as Description, 'fa-home large' as Icon,
    IsNull(m.UpdateDate,m.CreateDate) as ModifiedDate, 'Property' as TypeName
    From MLSDatas m
    Inner Join Addresses a on a.AddressId = m.AddressFK 
    Left Join MLSContacts mc on mc.MLSDataFK = m.MlsDataId
    Left Join Contacts c on ContactId = ContactFK
    Left Join People p on PersonId = PersonFK
    Left Join MLSAgents ma on ma.MLSDataFK = m.MlsDataId
    Left Join Agents ag on ag.AgentId = ma.AgentFK
    Left Join People p2 on p2.PersonId = ag.PersonFK
    Left Join PersonPhones pp on pp.PersonFK = p.PersonId
    Left Join Phones ph on ph.PhoneId = pp.PhoneFK
    Left Join PersonEmails pe on pe.PersonFK = p.PersonId
    Left Join Emails e on e.EmailId = pe.EmailFK
    Where m.MLSNumber like '%'+@term+'%' or StreetLine1 like '%'+@term+'%' 
    or p.FirstName like '%'+@term+'%' or p.LastName like '%'+@term+'%' or p.FirstName + ' ' + p.LastName like '%'+@term+'%'
    or p2.FirstName like '%'+@term+'%' or p2.LastName like '%'+@term+'%' or p2.FirstName + ' ' + p2.LastName like '%'+@term+'%'
    or ph.PhoneNumber like '%'+@term+'%'
    or e.EmailAddress like '%'+@term+'%'

    Union ALL

    Select Distinct l.ListingId as ResultId, l.DisplayTitle as ResultName, '#/listing/'+convert(varchar(20),l.ListingId) as ResultLink, l.DisplayTitle as Description, 'fa-globe large' as Icon,
    IsNull(m.UpdateDate,m.CreateDate) as ModifiedDate, 'Listing' as TypeName
    From Listings l
    Inner Join MLSDatas m on m.MLSDataId = l.MLSDataFK
    Inner Join Addresses a on a.AddressId = m.AddressFK 
    Left Join MLSContacts mc on mc.MLSDataFK = MlsDataId
    Left Join Contacts c on ContactId = ContactFK
    Left Join People p on PersonId = PersonFK
    Left Join PersonPhones pp on pp.PersonFK = p.PersonId
    Left Join Phones ph on ph.PhoneId = pp.PhoneFK
    Left Join PersonEmails pe on pe.PersonFK = p.PersonId
    Left Join Emails e on e.EmailId = pe.EmailFK
    Where m.MLSNumber like '%'+@term+'%' or StreetLine1 like '%'+@term+'%' 
    or p.FirstName like '%'+@term+'%' or p.LastName like '%'+@term+'%' or p.FirstName + ' ' + p.LastName like '%'+@term+'%'
    or ph.PhoneNumber like '%'+@term+'%'
    or e.EmailAddress like '%'+@term+'%'

    Union All

    Select Distinct c.ContactId as ResultId, p.FirstName + ' ' + p.LastName as ResultName, '#/contact/'+convert(varchar(20),c.ContactId) as ResultLink, p.FirstName + ' ' + p.LastName as Description, 'fa-book large' as Icon,
    IsNull(p.UpdateDate,p.CreateDate) as ModifiedDate, 'Contact' as TypeName
    From MLSDatas m
    Inner Join Addresses a on a.AddressId = m.AddressFK 
    Left Join MLSContacts mc on mc.MLSDataFK = m.MlsDataId
    Left Join Contacts c on ContactId = ContactFK
    Left Join People p on PersonId = PersonFK
    Left Join PersonPhones pp on pp.PersonFK = p.PersonId
    Left Join Phones ph on ph.PhoneId = pp.PhoneFK
    Left Join PersonEmails pe on pe.PersonFK = p.PersonId
    Left Join Emails e on e.EmailId = pe.EmailFK
    Where m.MLSNumber like '%'+@term+'%' or StreetLine1 like '%'+@term+'%' 
    or p.FirstName like '%'+@term+'%' or p.LastName like '%'+@term+'%' or p.FirstName + ' ' + p.LastName like '%'+@term+'%'
    or ph.PhoneNumber like '%'+@term+'%'
    or e.EmailAddress like '%'+@term+'%'

    Union All

    Select Distinct ag.AgentId as ResultId, p.FirstName + ' ' + p.LastName as ResultName, '#/agent/'+convert(varchar(20),ag.AgentId) as ResultLink, p.FirstName + ' ' + p.LastName as Description, 'fa-suitcase large' as Icon,
    IsNull(p.UpdateDate,p.CreateDate) as ModifiedDate, 'Agent' as TypeName
    From MLSDatas m
    Inner Join Addresses a on a.AddressId = m.AddressFK 
    Left Join MLSAgents ma on ma.MLSDataFK = m.MlsDataId
    Left Join Agents ag on ag.AgentId = ma.AgentFK
    Left Join People p on PersonId = ag.PersonFK
    Left Join PersonPhones pp on pp.PersonFK = p.PersonId
    Left Join Phones ph on ph.PhoneId = pp.PhoneFK
    Left Join PersonEmails pe on pe.PersonFK = p.PersonId
    Left Join Emails e on e.EmailId = pe.EmailFK
    Where m.MLSNumber like '%'+@term+'%' or StreetLine1 like '%'+@term+'%' 
    or p.FirstName like '%'+@term+'%' or p.LastName like '%'+@term+'%' or p.FirstName + ' ' + p.LastName like '%'+@term+'%'
    or ph.PhoneNumber like '%'+@term+'%'
    or e.EmailAddress like '%'+@term+'%'
提前谢谢

很多问题
你在何处向左拐

您可以将其带到一个#temp中,以便只对其进行一次评估
但是由于你不总是给桌子贴标签,我不得不做一些猜测
然后加入#temp
并在#Temp上声明PK,因为它应该有助于查询优化器

insert into #temp (ID)
select m.MLSDataId   
  from MLSDatas m --
  Join People p on PersonId = PersonFK  --
  Join PersonPhones pp on pp.PersonFK = p.PersonId
  Join Phones ph on ph.PhoneId = pp.PhoneFK  --
  Join PersonEmails pe on pe.PersonFK = p.PersonId
  Join Emails e on e.EmailId = pe.EmailFK --  
Where m.MLSNumber like '%'+@term+'%' 
   or p.FirstName like '%'+@term+'%' 
   or p.LastName like '%'+@term+'%' 
   or p.FirstName + ' ' + p.LastName like '%'+@term+'%'
   or ph.PhoneNumber like '%'+@term+'%'
   or e.EmailAddress like '%'+@term+'%'


...
From Listings l 
join #temp as m 
  on m.MLSDataId = l.MLSDataFK

  on #tempID = 

我建议使用CTE,但是正如我在上面的评论中提到的,你应该考虑对数据库设计进行反规范化。即使“此数据库中的人员(姓名等)可以应用于用户、员工、代理、联系人或其他人”。针对该问题的一个建议是使用类型(例如用户、员工、代理、联系人或其他)。关于“让下一个走进来的人更容易识别外键指向的位置”,我不知道,也许吧。然而,它看起来确实很凌乱。最后是你的选择

如果你最终没有去规范化,我建议如下:

with cte_noWhere as
(
Select Distinct m.MLSDataId as ResultId, m.MLSNumber as ResultName, '#/mlsrecord/'+convert(varchar(20),m.MLSDataId) as ResultLink, a.StreetLine1 as Description, 'fa-home large' as Icon,
IsNull(m.UpdateDate,m.CreateDate) as ModifiedDate, 'Property' as TypeName,
m.MLSNumber as MLSNumber, StreetLine1, p.FirstName as FirstName, p.LastName as LastName, ph.PhoneNumber,
e.EmailAddress
From MLSDatas m
Inner Join Addresses a on a.AddressId = m.AddressFK 
Left Join MLSContacts mc on mc.MLSDataFK = m.MlsDataId
Left Join Contacts c on ContactId = ContactFK
Left Join People p on PersonId = PersonFK
Left Join MLSAgents ma on ma.MLSDataFK = m.MlsDataId
Left Join Agents ag on ag.AgentId = ma.AgentFK
Left Join People p2 on p2.PersonId = ag.PersonFK
Left Join PersonPhones pp on pp.PersonFK = p.PersonId
Left Join Phones ph on ph.PhoneId = pp.PhoneFK
Left Join PersonEmails pe on pe.PersonFK = p.PersonId
Left Join Emails e on e.EmailId = pe.EmailFK
Where p2.FirstName like '%'+@term+'%' or p2.LastName like '%'+@term+'%' or p2.FirstName + ' ' + p2.LastName like '%'+@term+'%'

Union ALL

Select Distinct l.ListingId as ResultId, l.DisplayTitle as ResultName, '#/listing/'+convert(varchar(20),l.ListingId) as ResultLink, l.DisplayTitle as Description, 'fa-globe large' as Icon,
IsNull(m.UpdateDate,m.CreateDate) as ModifiedDate, 'Listing' as TypeName,
m.MLSNumber as MLSNumber, StreetLine1, p.FirstName as FirstName, p.LastName as LastName, ph.PhoneNumber,
e.EmailAddress
From Listings l
Inner Join MLSDatas m on m.MLSDataId = l.MLSDataFK
Inner Join Addresses a on a.AddressId = m.AddressFK 
Left Join MLSContacts mc on mc.MLSDataFK = MlsDataId
Left Join Contacts c on ContactId = ContactFK
Left Join People p on PersonId = PersonFK
Left Join PersonPhones pp on pp.PersonFK = p.PersonId
Left Join Phones ph on ph.PhoneId = pp.PhoneFK
Left Join PersonEmails pe on pe.PersonFK = p.PersonId
Left Join Emails e on e.EmailId = pe.EmailFK

Union All

Select Distinct c.ContactId as ResultId, p.FirstName + ' ' + p.LastName as ResultName, '#/contact/'+convert(varchar(20),c.ContactId) as ResultLink, p.FirstName + ' ' + p.LastName as Description, 'fa-book large' as Icon,
IsNull(p.UpdateDate,p.CreateDate) as ModifiedDate, 'Contact' as TypeName,
m.MLSNumber as MLSNumber, StreetLine1, p.FirstName as FirstName, p.LastName as LastName, ph.PhoneNumber,
e.EmailAddress
From MLSDatas m
Inner Join Addresses a on a.AddressId = m.AddressFK 
Left Join MLSContacts mc on mc.MLSDataFK = m.MlsDataId
Left Join Contacts c on ContactId = ContactFK
Left Join People p on PersonId = PersonFK
Left Join PersonPhones pp on pp.PersonFK = p.PersonId
Left Join Phones ph on ph.PhoneId = pp.PhoneFK
Left Join PersonEmails pe on pe.PersonFK = p.PersonId
Left Join Emails e on e.EmailId = pe.EmailFK

Union All

Select Distinct ag.AgentId as ResultId, p.FirstName + ' ' + p.LastName as ResultName, 
'#/agent/'+convert(varchar(20),ag.AgentId) as ResultLink, p.FirstName + ' ' + p.LastName as Description, 
'fa-suitcase large' as Icon,
IsNull(p.UpdateDate,p.CreateDate) as ModifiedDate, 'Agent' as TypeName,
m.MLSNumber as MLSNumber, StreetLine1, p.FirstName as FirstName, p.LastName as LastName, ph.PhoneNumber,
e.EmailAddress
From MLSDatas m
Inner Join Addresses a on a.AddressId = m.AddressFK 
Left Join MLSAgents ma on ma.MLSDataFK = m.MlsDataId
Left Join Agents ag on ag.AgentId = ma.AgentFK
Left Join People p on PersonId = ag.PersonFK
Left Join PersonPhones pp on pp.PersonFK = p.PersonId
Left Join Phones ph on ph.PhoneId = pp.PhoneFK
Left Join PersonEmails pe on pe.PersonFK = p.PersonId
Left Join Emails e on e.EmailId = pe.EmailFK
)
select *
from cte_noWhere w
Where w.MLSNumber like '%'+@term+'%' or w.StreetLine1 like '%'+@term+'%' 
    or w.FirstName like '%'+@term+'%' 
        or w.LastName like '%'+@term+'%' or w.FirstName + ' ' + w.LastName like '%'+@term+'%'
    or w.PhoneNumber like '%'+@term+'%'
    or w.EmailAddress like '%'+@term+'%'

我在CTE中使用了您的大部分代码,并提取了common where子句。这可能会更快更有效,但我不确定。如果是的话,那可能是因为你现在做了一个where子句而不是41秒),虽然更干净(所以我就买它)。关于类型字段,这仍然允许使用多行相同的名称,这是我一直试图避免的。当一个人有多部电话和电子邮件时,这些电话和电子邮件不会与你建议的独特类型的每一行联系起来。此外,此模式在C#应用程序中运行良好,因为用户继承了“Person”类型,其他Person类型的实体也是如此。这看起来太复杂了,但它有很多原因。。。我排完了队。。。感谢您抽出时间回答。我仍在权衡数据库设计的选择,但我们有一位客户,在我引用该应用程序之前大约6个月,他就承诺了这个应用程序。。。“所以我现在有点时间紧张了。”布拉德尔,我完全理解。我去过那里,做过那件事。我只是觉得你应该知道其他方法,以及为什么另一种方法可能会更好。如果我的答案有帮助,请向上投票或单击复选标记选择答案,我们将不胜感激。:)祝你好运。cte只是语法。你能详细说明你的观点吗?不知道你是什么意思。不是我说的。@PaulKar。我没有投你反对票。即使我不认为你的回答有效率。在查看并思考了你的回答后,我似乎看不出有几个表格(例如地址、MLS联系人、联系人、MLS联系人、代理)去了哪里?除此之外,当Brad使用更多列时,您仅选择一列。看来你的答案不完整。@PaulKar。我需要画画吗?你把它变成临时工,然后加入临时工4次#temp是具体化的,只计算一次。困难的事情只能做一次。如果OP甚至不打算标记c0me列来自哪个表并提供MLSDatas的定义,我就不会花更多的精力。