哈希匹配(内部联接)在我的查询中花费50%

时间:2017-11-27 20:04:13

标签: sql-server tsql indexing sql-server-2012

我还没有与Hash Join进行过互动。 根据下图,我是否需要表tblFin_Invoices上的索引?

或者我需要在哪个表中创建索引以避免此Hash Join?

我有可能做些什么来缓解查询吗?

----------------------------------------------- -------------------------

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

enter image description here enter image description here

1 个答案:

答案 0 :(得分:1)

在@ValidInvoicesTable的第一个查询中使用的所有表也在第二个查询中。而不是使用@ValidInvoicesTable,使用该SELECT中的WHERE条件并替换第二个SELECT语句中的WHERE条件。

如果DateTime字段实际包含Time,我还会使用BETWEEN而不是两个语句进行日期比较,以获得与CAST / CONVERT EffectiveDate相同的结果。

我也会从tblFin_InvoiceDetails中加入。

我假设你要将@TempData表用于其他只是SELECT语句的东西。如果我错了,你应该完全删除关于@TempData表的DECLARE和INSERT INTO。

以下是我的建议。

declare  
     @EffDateFrom datetime = '2017-02-01',  
     @EffDateTo  datetime= '2017-12-31'

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,
                tblQuotes.PolicyTypeID,
                tblQuotes.TransactionTypeID, 
                tblQuotes.QuoteStatusID,
                tblQuotes.PolicyNumber,         
                tblQuotes.StateID, 
                SUM(ISNULL(tblDetailed.AmtBilled, 0)) 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
    LEFT  JOIN      tblFin_InvoiceDetail tblDetail ON tblDetail.InvoiceNum = INV.InvoiceNum AND tblDetail.ChargeType = 'P'
    WHERE 
            INV.Failed = 0
            AND CAST(dbo.tblQuotes.EffectiveDate as date) BETWEEN @EffDateFrom AND @EffDateTo 
            AND dbo.tblQuotes.LineGUID = '6E00868B-FFC3-4CA0-876F-CC258F1ED22D'
    GROUP BY INV.QuoteID,
                tblQuotes.QuoteGUID,
                tblQuotes.CompanyLocationGuid,
                tblQuotes.UnderwriterUserGuid,
                tblSubmissionGroup.InsuredGuid,
                tblProducerLocations.ProducerGUID,
                tblQuotes.ProducerContactGuid,
                INV.EffectiveDate,
                INV.InvoiceDate,
                tblQuotes.PolicyTypeID,
                tblQuotes.TransactionTypeID, 
                tblQuotes.QuoteStatusID,
                tblQuotes.PolicyNumber,         
                tblQuotes.StateID, 
                 [Dynamic_Data_SuretyPRC].BondRate,
                 [Dynamic_Data_SuretyPRC].BondAmount,
                 [Dynamic_Data_SuretyPRC].CompanyComm
    ORDER BY    INV.InvoiceDate