我正在尝试加入14个表,其中我需要使用左连接来连接几个表。 使用大约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
只有下表包含更多数据,而其他表的记录少于20
InvoiceDetails,QuoteMaster,QuoteItemDetails,QuoteBatchDetails ProductInvoice
以下是执行计划的链接
感谢。
答案 0 :(得分:1)
让我们从一个明显的错误开始:
(isnull(SQBD.BatchSellQty,0) > 0)
那个不可索引,所以不应该发生。说真的,在大多数情况下,BatchSellQty不应该是未知的(可空),或者你最好正确地处理null。该字段应该编入索引,我不确定我是否希望使用isNull - 可能有大量的批次。另请注意,过滤后的索引(条件> 0)可能适用于此。
其次,检查您是否拥有所有正确的索引,并且执行计划是有意义的。
你需要测试大量数据。指数统计可能会有所不同。检查时间花在哪里 - 它可能是tempdb,在这种情况下你真的需要一个很好的tempdb IO速度....并且它没有被输入端实现。
答案 1 :(得分:-1)
您可以尝试使用query hints来帮助SQL Server优化程序构建最佳查询执行计划。例如,您可以使用FORCE ORDER
语句强制加入表的顺序。如果您按顺序在每个步骤中以最小结果大小进行连接,则查询将执行得更快(可能需要尝试)。例如:
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)
在这种情况下,最佳订单将是
A join C join B = ~3 records x 1000 records = ~3000 records