查询运行时间太长而索引不起作用

时间:2013-05-22 16:03:49

标签: sql sql-server database indexing

我创建了一个索引来帮助一个非常长的28分钟qry跑得更快,而且似乎没有多大帮助。

这是我创建的索引

USE [NLTR201212_test]
GO
CREATE NONCLUSTERED INDEX [Billys Index, sysname,]
ON [dbo].[tblInsurance] ([TERM_REASON])
INCLUDE ([POLICY_NO],[IssueYear],[ISSUE_DATE],[LM_PLAN_CODE],[AMOUNT_INFORCE],[StatReserve],[StatReserveX],[DefPremReserve],[ExcessCashValue],[ExcessCashValueX],[STAT2_PUA_RES],[STAT2_OYT_RES],[StatOYTRes2X],[COMPANY_CODE],[PHASE_CODE],[SUB_PHASE_CODE],[ProdType])
GO

这是我创造的第一个索引,所以如果我以某种方式做错了我也不会感到惊讶。 TblInsurance确实有一个由五列(COMPANY_CODE, LINE_OFBUSINESS, POLICY_NO, PHASE_CODESUB_PHASE_CODE)组成的主键。

不知道还有什么可以帮助解决这个问题。

这是qry,

SELECT 
    qry_tempCashValue2.IssueYear, 
    qry_tempCashValue2.LM_PLAN_CODE, 
    Count(qry_tempCashValue2.POLICY_NO) AS CountOfPOLICY_NO, 
    qry_tempCashValue2.[Interest Rate Code]
FROM
(
    SELECT 
        qry_tempCashValue.POLICY_NO, 
        qry_tempCashValue.IssueYear, 
        qry_tempCashValue.ISSUE_DATE, 
        qry_tempCashValue.LM_PLAN_CODE, 
        qry_tempCashValue.AMOUNT_INFORCE, 
        qry_tempCashValue.StatReserve, 
        qry_tempCashValue.StatReserveX, 
        qry_tempCashValue.DefPremReserve, 
        qry_tempCashValue.ExcessCashValue, 
        qry_tempCashValue.ExcessCashValueX, 
        qry_tempCashValue.STAT2_PUA_RES, 
        qry_tempCashValue.STAT2_OYT_RES, 
        qry_tempCashValue.StatOYTRes2X, 
        qry_tempCashValue.[Calc Parameters Code], 
        Max(qry_tempCashValue.[Low Issue Date]) AS [MaxOfLow Issue Date], 
        qry_tempCashValue.[Interest Rate Code]
    FROM
    (
        SELECT 
            tblInsurance.POLICY_NO, 
            tblInsurance.IssueYear, 
            tblInsurance.ISSUE_DATE, 
            tblInsurance.LM_PLAN_CODE, 
            tblInsurance.AMOUNT_INFORCE, 
            tblInsurance.StatReserve, 
            tblInsurance.StatReserveX, 
            tblInsurance.DefPremReserve, 
            tblInsurance.ExcessCashValue, 
            tblInsurance.ExcessCashValueX, 
            tblInsurance.STAT2_PUA_RES, 
            tblInsurance.STAT2_OYT_RES, 
            tblInsurance.StatOYTRes2X, 
            qryPolyCalcParameters.[Calc Parameters Code], 
            qryPolyCalcParameters.[Low Issue Date], 
            qryPolyCalcParameters.[Interest Rate Code]
        FROM tblInsurance 
        INNER JOIN qryPolyLifeMasterPlans 
            ON tblInsurance.LM_PLAN_CODE = 
                qryPolyLifeMasterPlans.[LifeMaster Plan Code] 
        INNER JOIN qryPolyNonforfeitureValues 
            ON qryPolyLifeMasterPlans.[Nonforfeiture Value Code] = 
                qryPolyNonforfeitureValues.[Nonforfeiture Value Code] 
        INNER JOIN qryPolyCalcParameters 
            ON qryPolyNonforfeitureValues.[(Cash Value) Calc Parameters Code] = 
                qryPolyCalcParameters.[Calc Parameters Code]
        WHERE 
            qryPolyCalcParameters.[Low Issue Date]<[ISSUE_DATE] 
            AND tblInsurance.COMPANY_CODE='NL' 
            AND tblInsurance.LINE_OF_BUSINESS='IT' 
            AND tblInsurance.SchedNP='PAR'
            AND tblInsurance.TERM_REASON='A' 
            AND tblInsurance.ProdType='PERM' 
            AND tblInsurance.PHASE_CODE=0 
            AND tblInsurance.SUB_PHASE_CODE=1 
        ) qry_tempCashValue
    GROUP BY 
        qry_tempCashValue.POLICY_NO, 
        qry_tempCashValue.IssueYear, 
        qry_tempCashValue.ISSUE_DATE, 
        qry_tempCashValue.LM_PLAN_CODE, 
        qry_tempCashValue.AMOUNT_INFORCE, 
        qry_tempCashValue.StatReserve, 
        qry_tempCashValue.StatReserveX, 
        qry_tempCashValue.DefPremReserve, 
        qry_tempCashValue.ExcessCashValue, 
        qry_tempCashValue.ExcessCashValueX, 
        qry_tempCashValue.STAT2_PUA_RES, 
        qry_tempCashValue.STAT2_OYT_RES, 
        qry_tempCashValue.StatOYTRes2X, 
        qry_tempCashValue.[Calc Parameters Code], 
        qry_tempCashValue.[Interest Rate Code]
    ) qry_tempCashValue2
GROUP BY 
    qry_tempCashValue2.IssueYear, 
    qry_tempCashValue2.LM_PLAN_CODE, 
    qry_tempCashValue2.[Interest Rate Code];

GO

3 个答案:

答案 0 :(得分:2)

我认为你应该清理你的查询,而不是专注于添加索引。我不知道你为什么要嵌套这个,而不是一次只做一次和一次选择。

    SELECT 
        tblInsurance.POLICY_NO, 
        tblInsurance.IssueYear, 
        tblInsurance.ISSUE_DATE, 
        tblInsurance.LM_PLAN_CODE, 
        tblInsurance.AMOUNT_INFORCE, 
        tblInsurance.StatReserve, 
        tblInsurance.StatReserveX, 
        tblInsurance.DefPremReserve, 
        tblInsurance.ExcessCashValue, 
        tblInsurance.ExcessCashValueX, 
        tblInsurance.STAT2_PUA_RES, 
        tblInsurance.STAT2_OYT_RES, 
        tblInsurance.StatOYTRes2X, 
        qryPolyCalcParameters.[Calc Parameters Code], 
        max(qryPolyCalcParameters.[Low Issue Date]) AS [MaxOfLow Issue Date], 
        qryPolyCalcParameters.[Interest Rate Code]
    FROM tblInsurance 
    INNER JOIN qryPolyLifeMasterPlans 
        ON tblInsurance.LM_PLAN_CODE = 
            qryPolyLifeMasterPlans.[LifeMaster Plan Code] 
    INNER JOIN qryPolyNonforfeitureValues 
        ON qryPolyLifeMasterPlans.[Nonforfeiture Value Code] = 
            qryPolyNonforfeitureValues.[Nonforfeiture Value Code] 
    INNER JOIN qryPolyCalcParameters 
        ON qryPolyNonforfeitureValues.[(Cash Value) Calc Parameters Code] = 
            qryPolyCalcParameters.[Calc Parameters Code]
    WHERE 
        qryPolyCalcParameters.[Low Issue Date]<[ISSUE_DATE] 
        AND tblInsurance.COMPANY_CODE='NL' 
        AND tblInsurance.LINE_OF_BUSINESS='IT' 
        AND tblInsurance.SchedNP='PAR'
        AND tblInsurance.TERM_REASON='A' 
        AND tblInsurance.ProdType='PERM' 
        AND tblInsurance.PHASE_CODE=0 
        AND tblInsurance.SUB_PHASE_CODE=1 
GROUP BY 
    tblInsurance.POLICY_NO, 
    tblInsurance.IssueYear, 
    tblInsurance.ISSUE_DATE, 
    tblInsurance.LM_PLAN_CODE, 
    tblInsurance.AMOUNT_INFORCE, 
    tblInsurance.StatReserve, 
    tblInsurance.StatReserveX, 
    tblInsurance.DefPremReserve, 
    tblInsurance.ExcessCashValue, 
    tblInsurance.ExcessCashValueX, 
    tblInsurance.STAT2_PUA_RES, 
    tblInsurance.STAT2_OYT_RES, 
    tblInsurance.StatOYTRes2X, 
    qryPolyCalcParameters.[Calc Parameters Code], 
    qryPolyCalcParameters.[Interest Rate Code]

那应该有所帮助。然后我们可以看到摆脱其他嵌套。这是你的子选择,正在扼杀你的表现。

答案 1 :(得分:0)

我认为您可以将查询转换为:

SELECT 
    qry_tempCashValue.IssueYear, 
    qry_tempCashValue.LM_PLAN_CODE, 
    Count(distinct qry_tempCashValue.POLICY_NO) AS CountOfPOLICY_NO, 
    qry_tempCashValue.[Interest Rate Code]
FROM
(
        SELECT 
            tblInsurance.POLICY_NO, 
            tblInsurance.IssueYear, 
            tblInsurance.ISSUE_DATE, 
            tblInsurance.LM_PLAN_CODE, 
            tblInsurance.AMOUNT_INFORCE, 
            tblInsurance.StatReserve, 
            tblInsurance.StatReserveX, 
            tblInsurance.DefPremReserve, 
            tblInsurance.ExcessCashValue, 
            tblInsurance.ExcessCashValueX, 
            tblInsurance.STAT2_PUA_RES, 
            tblInsurance.STAT2_OYT_RES, 
            tblInsurance.StatOYTRes2X, 
            qryPolyCalcParameters.[Calc Parameters Code], 
            qryPolyCalcParameters.[Low Issue Date], 
            qryPolyCalcParameters.[Interest Rate Code]
        FROM tblInsurance 
        INNER JOIN qryPolyLifeMasterPlans 
            ON tblInsurance.LM_PLAN_CODE = 
                qryPolyLifeMasterPlans.[LifeMaster Plan Code] 
        INNER JOIN qryPolyNonforfeitureValues 
            ON qryPolyLifeMasterPlans.[Nonforfeiture Value Code] = 
                qryPolyNonforfeitureValues.[Nonforfeiture Value Code] 
        INNER JOIN qryPolyCalcParameters 
            ON qryPolyNonforfeitureValues.[(Cash Value) Calc Parameters Code] = 
                qryPolyCalcParameters.[Calc Parameters Code]
        WHERE 
            qryPolyCalcParameters.[Low Issue Date]<[ISSUE_DATE] 
            AND tblInsurance.COMPANY_CODE='NL' 
            AND tblInsurance.LINE_OF_BUSINESS='IT' 
            AND tblInsurance.SchedNP='PAR'
            AND tblInsurance.TERM_REASON='A' 
            AND tblInsurance.ProdType='PERM' 
            AND tblInsurance.PHASE_CODE=0 
            AND tblInsurance.SUB_PHASE_CODE=1 
        ) qry_tempCashValue
GROUP BY 
    qry_tempCashValue.IssueYear, 
    qry_tempCashValue.LM_PLAN_CODE, 
    qry_tempCashValue.[Interest Rate Code];

这消除了内部聚合并使用count(distinct)计算策略。根据您的数据,这可能不会返回相同的结果。

对于索引,一个好的起点是在连接中使用的每个表的键上都有一个索引。使用where的{​​{1}} tblInsrance子句中的所有列中的另一列。

答案 2 :(得分:0)

这是简化的整个查询。

SELECT 
    qry_tempCashValue2.IssueYear, 
    qry_tempCashValue2.LM_PLAN_CODE, 
    Count(qry_tempCashValue2.POLICY_NO) AS CountOfPOLICY_NO, 
    qry_tempCashValue2.[Interest Rate Code]
FROM
(
    SELECT distinct
        tblInsurance.POLICY_NO, 
        tblInsurance.IssueYear, 
        tblInsurance.ISSUE_DATE, 
        tblInsurance.LM_PLAN_CODE, 
        tblInsurance.AMOUNT_INFORCE, 
        tblInsurance.StatReserve, 
        tblInsurance.StatReserveX, 
        tblInsurance.DefPremReserve, 
        tblInsurance.ExcessCashValue, 
        tblInsurance.ExcessCashValueX, 
        tblInsurance.STAT2_PUA_RES, 
        tblInsurance.STAT2_OYT_RES, 
        tblInsurance.StatOYTRes2X, 
        qryPolyCalcParameters.[Calc Parameters Code], 
        qryPolyCalcParameters.[Interest Rate Code]
        FROM tblInsurance 
        INNER JOIN qryPolyLifeMasterPlans 
            ON tblInsurance.LM_PLAN_CODE = 
                qryPolyLifeMasterPlans.[LifeMaster Plan Code] 
        INNER JOIN qryPolyNonforfeitureValues 
            ON qryPolyLifeMasterPlans.[Nonforfeiture Value Code] = 
                qryPolyNonforfeitureValues.[Nonforfeiture Value Code] 
        INNER JOIN qryPolyCalcParameters 
            ON qryPolyNonforfeitureValues.[(Cash Value) Calc Parameters Code] = 
                qryPolyCalcParameters.[Calc Parameters Code]
        WHERE 
            qryPolyCalcParameters.[Low Issue Date]<[ISSUE_DATE] 
            AND tblInsurance.COMPANY_CODE='NL' 
            AND tblInsurance.LINE_OF_BUSINESS='IT' 
            AND tblInsurance.SchedNP='PAR'
            AND tblInsurance.TERM_REASON='A' 
            AND tblInsurance.ProdType='PERM' 
            AND tblInsurance.PHASE_CODE=0 
            AND tblInsurance.SUB_PHASE_CODE=1 
    ) qry_tempCashValue2
GROUP BY 
    qry_tempCashValue2.IssueYear, 
    qry_tempCashValue2.LM_PLAN_CODE, 
    qry_tempCashValue2.[Interest Rate Code];

GO