简体   繁体   English

提高连接14个表的SQL查询的性能

[英]Improve Performance of SQL query joining 14 tables

I am trying to join 14 tables in which few tables I need to join using left join. 我正在尝试加入14个表,其中我需要使用左联接来联接的表很少。 With the existing data which is around 7000 records,its taking around 10 seconds to execute the below query.I am afraid what if the records are more than million.Please help me improve the performance of the below query. 现有的数据大约有7000条记录,大约需要10秒才能执行以下查询。如果记录数超过百万,恐怕会怎样。请帮助我改善以下查询的性能。

CREATE proc [dbo].[GetTodaysActualInvoiceItemSoldHistory]                          
@fromdate datetime,        
@todate datetime        
as                          

Begin                    

select SDID.InvoiceDate as [Sold Date],Cust.custCompanyName as [Sold To] ,   
case SQBD.TransferNo  when '0' then IVM.VendorName else SQBD.TransferNo end as [Purchase From],  
SQBD.BatchSellQty as SoldQty,SQID.SellPrice,  
SDID.InvoiceNo as [Sales Invoice No],INV.PRInvoiceNo as [PO Invoice No],INV.PRInvoiceDate as [PO Invoice Date],   
SQID.ItemDesc as [Item Description],SQID.NetPrice,SDHM.DeliveryHeaderMasterName as   DeliveryHeaderName,    
SQID.ItemCode as [Item Code],           
SQBD.BatchNo,SQBD.ExpiryDate,SQID.Amount,   
SQID.Dept_ID as Dept_ID,              
Dept_Name as [Department],SQID.Catg_ID as Catg_ID,                                    
Category_Name as [Category],SQID.Brand_ID as Brand_ID,               
BrandName as BrandName, SQID.Manf_Id as Manf_Id,                             
Manf.ManfName as [Manufacturer],              
STM.TaxName, SQID.Tax_ID as Tax_ID,              
INV.VendorID as VendorID,              
SQBD.ItemID,SQM.Isdeleted,  
SDHM.DeliveryHeaderMasterID,Cust.CustomerMasterID        
 from  SD_QuotationMaster SQM                  
inner join  SD_InvoiceDetails SDID on SQM.QuoteID = SDID.QuoteID                
inner join  SD_QuoteItemDetails SQID on SDID.QuoteID = SQID.QuoteID               
inner join  SD_QuoteBatchDetails SQBD on SDID.QuoteID = SQBD.QuoteID and SQID.ItemID=SQBD.ItemID              
inner join  INV_ProductInvoice INV on SQBD.InvoiceID=INV.ProductInvoiceID              
inner jOIN  INV_VendorMaster IVM ON INV.VendorID = IVM.VendorID       
inner jOIN  Sys_TaxMaster STM ON SQID.Tax_ID = STM.Tax_ID                 
inner join Cust_CustomerMaster Cust on SQM.CustomerMasterID = Cust.CustomerMasterID    
left jOIN  INV_DeptartmentMaster Dept ON SQID.Dept_ID = Dept.Dept_ID                                       
left jOIN  INV_BrandMaster BRD ON SQID.Brand_ID = BRD.Brand_ID                                       
left jOIN  INV_ManufacturerMaster  Manf ON SQID.Manf_Id = Manf.Manf_Id                
left join INV_CategoryMaster CAT ON SQID.Catg_ID = CAT.Catg_ID                                                              
left join SLRB_DeliveryCustomerMaster SDCM on SQM.CustomerMasterID=SDCM.CustomerMasterID and SQM.DeliveryHeaderMasterID=SDCM.DeliveryHeaderMasterID                                       
left join SLRB_DeliveryHeaderMaster SDHM on SDCM.DeliveryHeaderMasterID=SDHM.DeliveryHeaderMasterID                               
where (SQM.IsDeleted=0)  and SQBD.BatchSellQty > 0          

and SDID.InvoiceDate between @fromdate and @todate                
order by ItemDesc                     

End 

Only the below tables contain more data while other tables have records less than 20 只有下面的表包含更多的数据,而其他表的记录少于20

InvoiceDetails, QuoteMaster, QuoteItemDetails, QuoteBatchDetails ProductInvoice InvoiceDetails,QuoteMaster,QuoteItemDetails,QuoteBatchDetails ProductInvoice

Below is the link for execution plan 以下是执行计划的链接

http://jmp.sh/CSZc2x2 http://jmp.sh/CSZc2x2

Thanks. 谢谢。

Let's start with an obvious error: 让我们从一个明显的错误开始:

(isnull(SQBD.BatchSellQty,0) > 0)

That one is not indexable, so it should not happen. 那是不可索引的,因此它不应发生。 Seriously, BatchSellQty should not be unknown (nullable) in most cases, or you better handle null properly. 严重地,在大多数情况下BatchSellQty不应是未知的(可为空),否则您最好正确处理null。 That field should be indexed and I am not sure I would like that with an isNull - there are likely tons of batches. 该字段应该被索引,我不确定是否要使用isNull-可能会有很多批次。 Also note that a filtered index (condition >0) may work here. 另请注意,此处可以使用过滤索引(条件> 0)。

Second, check that you have all proper indices and the execution plan makes sense. 其次,检查您是否具有所有适当的索引,并且执行计划是否合理。

Thids, you have to test with a ton of data. 流行,您必须测试大量数据。 Index statistics may make a difference. 索引统计可能有所不同。 Check where the time is spent - it may be tempdb in which case you really need a good tempdb IO speed.... and it is not realted to the input side. 检查时间花在哪里-可能是tempdb,在这种情况下,您确实需要良好的tempdb IO速度...。并且它不会在输入端实现。

You can try to use query hints to help SQL Server optimizer build a optimal query execution plan. 您可以尝试使用查询提示来帮助SQL Server优化器建立最佳查询执行计划。 For example, you can force the order of tables will be joined, using FORCE ORDER statement. 例如,您可以使用FORCE ORDER语句强制连接表的顺序。 If you order your tables in order that joins with minimum result size at each step, query will execute faster (may be, needs to try). 如果您按顺序对表进行排序,以便在每个步骤中以最小的结果大小进行连接,则查询将更快地执行(可能需要尝试)。 Example: 例:

We need to A join B join C
If A join B = 2000 records x 1000 records = ~400 records (we suspect this result)
And A join C = 2000 records x 10 records = ~3 records (and this)
And B join C = 1000 records x 10 records = 10 000 records (and this)

In this case optimal order will be 在这种情况下,最佳顺序为

A join C join B = ~3 records x 1000 records = ~3000 records

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM