【问题标题】:Is there a better way to join several tables rather than user 'INNER JOIN'有没有更好的方法来连接多个表而不是用户'INNER JOIN'
【发布时间】:2015-12-25 21:12:06
【问题描述】:

我正在编写一个查询以从八个表中获取 50 列。只是出于好奇,有没有更好的方法来获取数据而不是使用一系列inner join Table A on Table B.orderNumber = Table A.OrderNumber 来获取表 A-H?

运行的数据库是 SQL Server 2008。

这是我仍在写信的初始查询:

SELECT
    /*Buyer and Seller information for order number */
   [QCV_BuyerSellers].[OrderNumber] AS OrderNum
  ,[QCV_BuyerSellers].[OrderGuid] AS Order_GUID
  ,[QCV_BuyerSellers].[Buyer1_EntityTypeId] AS ENT_TYPE
  ,[QCV_BuyerSellers].[Buyer1_EntityTypeName] AS ENT_TYPE_NAME
  ,[QCV_BuyerSellers].[Buyer1_FullName] AS FULL_NAME
  ,[QCV_BuyerSellers].[Buyer1_FirstName] AS BF_Name
  ,[QCV_BuyerSellers].[Buyer1_MiddleName] AS BM_Name
  ,[QCV_BuyerSellers].[Buyer1_LastName] AS BL_Name
  ,[QCV_BuyerSellers].[Buyer1_TIN] AS B_Tin1
  ,[QCV_BuyerSellers].[Buyer1_PhoneHome] AS B_PhoneHome
  ,[QCV_BuyerSellers].[Buyer1_PhoneWork] AS B_PhoneWork

  ,[QCV_BuyerSellers].[Buyer2_FullName] AS FULL_NAME2
  ,[QCV_BuyerSellers].[Buyer2_FirstName] AS BF_Name2
  ,[QCV_BuyerSellers].[Buyer2_MiddleName] AS BM_Name2
  ,[QCV_BuyerSellers].[Buyer2_LastName] AS BL_Name2
  ,[QCV_BuyerSellers].[Buyer2_TIN] AS B_Tin2
  ,[QCV_BuyerSellers].[Buyer2_PhoneHome] AS B_PhoneHome2
  ,[QCV_BuyerSellers].[Buyer2_PhoneWork] AS B_PhoneWork2

  ,[QCV_BuyerSellers].[Seller1_FirstName] AS SF_Name
  ,[QCV_BuyerSellers].[Seller1_MiddleName] AS SM_Name
  ,[QCV_BuyerSellers].[Seller1_LastName] AS SL_Name
  ,[QCV_BuyerSellers].[Seller1_TIN] AS S_Tin
  ,[QCV_BuyerSellers].[Seller1_PhoneHome] AS S_PhoneHome
  ,[QCV_BuyerSellers].[Seller1_PhoneWork] AS S_PhoneWork

  ,[QCV_BuyerSellers].[Seller2_FirstName] AS SF_Name2
  ,[QCV_BuyerSellers].[Seller2_MiddleName] AS SM_Name2
  ,[QCV_BuyerSellers].[Seller2_LastName] AS SL_Name2
  ,[QCV_BuyerSellers].[Seller2_TIN] AS S_Tin2
  ,[QCV_BuyerSellers].[Seller2_PhoneHome] AS S_PhoneHome2
  ,[QCV_BuyerSellers].[Seller2_PhoneWork] AS S_PhoneWork2

  /*OMFILE Property table fields by order number */
  ,[OMFILE_PROPERTY].[PropertyAddress1] AS Prop_Adress
  ,[OMFILE_PROPERTY].[PropertyCity] AS Prop_City
  ,[OMFILE_PROPERTY].PropertyCounty AS Prop_County
  ,[OMFILE_PROPERTY].PropertyState AS Prop_State 
  ,[OMFILE_PROPERTY].PropertyZip AS Prop_Zip
  ,[OMFILE_PROPERTY].PropertyBriefLegal1 AS Prop_Brief1
  ,[OMFILE_PROPERTY].PropertyBriefLegal2 AS Prop_Brief2

  ,[OMEXT2_SUBDIVISION].SubdPUDFlag AS SD_PUD_FLAG
  ,[OMEXT2_SUBDIVISION].SubdCondominiumFlag AS SD_Condo_Flag

   /*OMFILE Payoff Fields for order number */
  ,[OMFILE_PAYOFFS].[Payoff1Name] 
  ,[OMFILE_PAYOFFS].[Payoff1LoanNumber] 
  ,[OMFILE_PAYOFFS].[Payoff1Phone] 

  ,[OMFILE_PAYOFFS].[Payoff2Name] 
  ,[OMFILE_PAYOFFS].[Payoff2LoanNumber] 
  ,[OMFILE_PAYOFFS].[Payoff2Phone]

  /*Loan Number & Amount From  OMFILE_LENDERLOAN table */
  ,[OMFILE_LENDERLOAN].[LoanNumber]  
  ,[OMFILE_LENDERLOAN].[LoanAmount] 

 FROM [REO].[dbo].[V_BuyerSellers] 
  INNER JOIN [REO].[dbo].[OMFILE_PROPERTY] 
  on V_BuyerSellers_Flat.OrderNumber = OMFILE_PROPERTY.OrderNumber
  INNER JOIN 
  [REO].[dbo].[OMEXT2_SUBDIVISION]
  on [REO].[OrderNumber] = [OMEXT2_SUBDIVISION].[OrderNumber]
  INNER JOIN [REO].[dbo].[OMFILE_PAYOFFS] 
  on [OMFILE_PROPERTY].[OrderNumber] = [OMFILE_PAYOFFS].[OrderNumber] 
  INNER JOIN [REO].[dbo].[OMFILE_LENDERLOAN] 
  on [OMFILE_PAYOFFS].[OrderNumber] = [OMFILE_LENDERLOAN].[OrderNumber] 

  WHERE [QCV_BuyerSellers].[OrderNumber] = 'QCT-8735410'

【问题讨论】:

  • 可能不会,但您应该发布有关您的表结构和用于加入的查询的信息以获得更好的反馈
  • 同意@Samcd。在某些情况下,如果其中一些表足够小且足够稳定,并且您经常查询它们,那么将整个表加载到您的程序中并将它们保留在那里以供多个数据库查询可能是有利可图的。但是很可能数据库服务器在缓存和优化方面会比你做得更好 - 假设你已经创建了使这些连接有效的索引。最后一点非常重要。你有那些索引吗?
  • 据我所知没有,但是连接顺序取决于各个表中的数据可以帮助您在某些情况下获得更好的性能,请查看sql-server-performance.com/2006/tuning-joins
  • 在这种情况下,创建查询结果的索引视图可以提高性能。此 Stack Overflow 答案包含有关 SQL Server 中的索引视图的更多信息 - stackoverflow.com/questions/3986366/…
  • 如果您处理非常大的表并且您知道,您只需要几行(预选),CTE 可能是一个好主意。如果您仅在特殊条件下需要子数据,则 APPLY 可以提供更好的计划。但是 - 在大多数情况下! - 不应该试图巧妙地优化优化器;-) 在大多数情况下,索引和统计数据、缓存和重构的隐式使用将接近最佳...

标签: sql sql-server-2008 join inner-join


【解决方案1】:

一般来说,JOINS 比使用老式方法提供更好的性能和可读性,即:WHERE 用于 PK = FK

我会坚持使用JOINS

如果性能是一个问题,我建议您使用SQL Profiler 进行完整分析。

我还建议编写一个视图,以便在您的复杂查询的 SELECT 上获得更好的性能。

【讨论】:

  • 好吧,如果您要对某个答案投反对票,那么您应该向全体观众解释您的投反对票。
  • 嗯,应该像其他人一样在评论中回答 No. 呵呵。
  • 我没有投反对票,但是您的答案和问题之间的联系对我来说不够清楚。例如,建议编写视图可以有多种解释方式,其中一些会对性能产生负面影响。此外,引用WHERE 子句相当奇怪,考虑到示例查询中唯一的连接是简单的一键,OP 没有提到它。
  • @AdamMartin Where 子句可以用来替代 sql join。不建议这样做。但它仍然是。 it.toolbox.com/blogs/data-analytics/…
  • 我知道它可以使用,因为 OP 想要改进它只是奇怪的建议......
【解决方案2】:

我建议从运行查询开始时使用“包含实际执行计划”(Ctrl-M 切换此功能的开/关)并寻找可以提高性能的缺失索引。您的查询没有任何可以重构的明显缺陷。看起来您已经在使用视图,您可以从此查询创建一个新视图并为其编制索引,但不能保证索引视图会比引用索引表的视图执行得更好,通常是底层视图上的索引表仍在使用中。

有一些方法可以避免连接多个表对性能造成的影响,但它们也有其缺点。您可以从此查询创建一个没有WHERE 的表并索引OrderNumber 字段。如果您还没有准备好实施适当的数据仓库,那将是一条黑暗的道路,因为您最终可能会得到很多一次性报告表,并且根据环境的不同,它可能需要在不合理的间隔。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-13
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多