【发布时间】:2018-05-11 03:56:32
【问题描述】:
我还没有与Hash Join 互动过。
根据下图,我需要在表 tblFin_Invoices 上建立索引吗?
或者我需要为哪个表创建索引以避免这种哈希连接?
我可以做些什么来缓解查询吗?
----------------------------------------------- -------------------------
declare
@EffDateFrom datetime = '2017-02-01',
@EffDateTo datetime= '2017-12-31'
DECLARE @ValidInvoicesTable TABLE (InvoiceNum INT PRIMARY KEY)
INSERT INTO @ValidInvoicesTable
SELECT DISTINCT INV.InvoiceNum
FROM tblFin_Invoices INV
INNER JOIN tblQuotes ON INV.QuoteID = tblQuotes.QuoteID
--INNER JOIN tblClientOffices ON tblQuotes.QuotingLocationGuid = tblClientOffices.OfficeGUID
WHERE (INV.Failed = 0)
AND dateDiff(d, @EffDateFrom, dbo.tblQuotes.EffectiveDate) >= 0
AND dateDiff(d, @EffDateTo, dbo.tblQuotes.EffectiveDate) <= 0
AND dbo.tblQuotes.LineGUID = '6E00868B-FFC3-4CA0-876F-CC258F1ED22D'
DECLARE @TempData TABLE(
[QuoteID] int,
[QuoteGUID] [uniqueidentifier] NOT NULL,
[CompanyLocationGuid] [uniqueidentifier] NULL,
[UnderwriterUserGuid] [uniqueidentifier] NULL,
[InsuredGuid] [uniqueidentifier] NULL,
[ProducerGuid] [uniqueidentifier] NULL,
[ProducerContactGuid] [uniqueidentifier] NULL,
[EffectiveDate] datetime NULL,
--[InvoiceDate] datetime NULL,
[AccountingDate] datetime NULL,
[PolicyTypeID] tinyint NOT NULL, --------------
[TransactionTypeID] varchar(2) NULL,
[QuoteStatusID] tinyint NOT NULL,
[PolicyNumber] [varchar](150) NULL,
[StateID] [char](2) NULL,
[Premium] [money] NULL,
BondRate decimal (5,4) NULL,
[PenalLiability] [money] NULL,
[CompanyCommission] decimal(3,2) NULL
)
INSERT INTO @TempData
SELECT
INV.QuoteID,
tblQuotes.QuoteGUID,
tblQuotes.CompanyLocationGuid,
tblQuotes.UnderwriterUserGuid,
tblSubmissionGroup.InsuredGuid,
tblProducerLocations.ProducerGUID,
tblQuotes.ProducerContactGuid,
INV.EffectiveDate,
INV.InvoiceDate,
--dbo.CalcAccountingDate(tblQuotes.QuoteStatusID,INV.invoicedate,INV.effectivedate, tblQuotes.EndorsementEffective) AccountingDate,
tblQuotes.PolicyTypeID,
tblQuotes.TransactionTypeID,
tblQuotes.QuoteStatusID,
tblQuotes.PolicyNumber,
tblQuotes.StateID,
(SELECT ISNULL(SUM(tblFin_InvoiceDetails.AmtBilled), 0)
FROM tblFin_InvoiceDetails
WHERE (tblFin_InvoiceDetails.ChargeType = 'P')
AND (tblFin_InvoiceDetails.InvoiceNum = INV.InvoiceNum))
AS Premium,
[Dynamic_Data_SuretyPRC].BondRate,
[Dynamic_Data_SuretyPRC].BondAmount,
[Dynamic_Data_SuretyPRC].CompanyComm
FROM tblFin_Invoices INV
INNER JOIN tblQuotes ON INV.QuoteID = tblQuotes.QuoteID
INNER JOIN tblProducerLocations ON INV.ProducerLocationGUID = tblProducerLocations.ProducerLocationGUID
INNER JOIN tblSubmissionGroup ON tblQuotes.SubmissionGroupGuid = tblSubmissionGroup.SubmissionGroupGUID
LEFT JOIN [dbo].[Dynamic_Data_SuretyPRC] ON Dynamic_Data_SuretyPRC.QuoteGUID = tblQuotes.QuoteGUID
WHERE INV.InvoiceNum IN (SELECT * FROM @ValidInvoicesTable)
ORDER BY INV.InvoiceDate
--select * from @TempData
【问题讨论】:
-
老实说,我认为您需要进一步回顾您的查询。填充该表变量具有多个 nonSARGable 谓词。更糟糕的是,您根本不需要此处发布的代码中的 table 变量。您可以删除该表变量并重新编写谓词,以使列不在函数内。
-
谢谢肖恩。你认为我应该放弃哪张桌子?第一个 (@ValidInvoicesTable) 或第二个 (@TempData)。我创建第一个 (@ValidInvoicesTable) 的原因是出于性能目的。如果我使用
WHERE INV.InvoiceNum IN (SELECT * FROM @ValidInvoicesTable)- 查询运行得更快。 -
我可能会放弃他们两个。我什至没有注意到你正在使用其中的两个。我认为您希望所有具有有效日期的行都在两个日期参数之间?不太确定你在那里做什么。但这可以在没有所有表变量的情况下在单个 select 语句中完成(根据行数,这可能成为它们自己的性能瓶颈)。
-
如果查询中的大部分时间都花在优化操作上,即进行索引查找和哈希匹配,那么这是优化的。如果是扫描,我会担心的。这是一个误报,我同意@SeanLange 在这里您需要查看表变量和结构。查询很难阅读,也很难执行。
标签: sql-server tsql indexing sql-server-2012