我们可以使用JOIN的最佳表数是多少?

时间:2017-09-18 09:47:06

标签: sql-server sql-server-2008 join sql-server-2012

我有一个查询从7个表中获取记录。所有这些表都是JOINed以获取详细信息,少数表使用不同的ON子句多次。所以查询中有10个JOIN。我们如何优化查询以获得更好的性能?我们已经在JOIN列上有索引。我们可以做些什么来减少JOIN的数量?我使用兼容级别为2008的MS SQL 2012。

查询:

SELECT TOP 100
        MT.ProjectId, 
        matRef, 
        matDescription, 
        matKeyDescription, 
        matOpenDate, 
        matUFN, 
        matBranchRef, 
        matClosedDate, 
        ERN1.feeRef, 
        WorkTypeCode, 
        DPT.deptNo AS matDeptRef, 
        PreviousRef, 
        MT.ApplicationID, 
        MatterCompleted, 
        CASE WHEN MLC.PFCivil_MatterCount = 0 THEN 0 ELSE 1 END AS IsCPF, 
        CASE WHEN MLC.PF_MatterCount = 0 THEN 0 ELSE 1 END AS IsPF, 
        CASE WHEN MLC.Family_MatterCount = 0 THEN 0 ELSE 1 END AS IsFM, 
        CASE WHEN MLC.WL_MatterCount = 0 THEN 0 ELSE 1 END AS IsWills, 
        CASE WHEN MLC.Convey_MatterCount = 0 THEN 0 ELSE 1 END AS IsConvey, 
        CASE WHEN MLC.Probate_MatterCount = 0 THEN 0 ELSE 1 END AS IsProbate, 
        CASE WHEN MLC.PI_MatterCount = 0 THEN 0 ELSE 1 END AS IsPi, 
        CASE WHEN MLC.PIPortal_MatterCount = 0 THEN 0 ELSE 1 END AS IsPiPortal, 
        CASE WHEN MLC.CM_MatterCount = 0 THEN 0 ELSE 1 END AS IsChest, 
        CASE WHEN MLC.Campaigns_MatterCount = 0 THEN 0 ELSE 1 END AS IsMarketing, 
        CASE WHEN MLC.PFFamilyFixedFee_MatterCount = 0 THEN 0 ELSE 1 END AS IsPFFamilyFixedFeeMatter, 
        ERN2.feeRef AS MatPartner, 
        MatPFCertificateNo, 
        CASE WHEN MT.matClosedDate = {d''1753-01-01''} THEN 0 ELSE 1 END AS IsArchived,
        '''' Modules,
        MT.ChargeDescID,
        MT.MatterTypeID, 
        PrimaryClient.ClientName, 
        MB.LastAccDate, 
        MB.LastBillDate, 
        MB.LastClientDate, 
        MB.LastTimeDate
    FROM dbo.Matter AS MT 
    JOIN dbo.Departments AS DPT ON DPT.deptID = MT.deptID 
    JOIN dbo.Earners AS ERN1 ON ERN1.MemberId = MT.MatFeeMemId 
    JOIN dbo.Earners AS ERN2 ON ERN2.MemberId = MT.matPartnerMemId 
    JOIN dbo.WorkTypes AS WT ON WT.WorkTypeID = MT.WorkTypeID 
    JOIN dbo.ivw_MatterLinkCount AS MLC ON MLC.ProjectId = MT.ProjectId 
    JOIN dbo.Banks AS ClientBank ON MT.matClientBank = ClientBank.bankID
    JOIN dbo.Banks AS OfficeBank ON MT.matOfficeBank = OfficeBank.bankID
    JOIN dbo.Banks AS DepositBank ON MT.matDepositBank = DepositBank.bankID
    JOIN uvw_MatterPrimaryClient AS PrimaryClient ON PrimaryClient.ProjectId = MT.ProjectId
    JOIN dbo.MatterBalance AS MB ON MT.ProjectId = MB.ProjectID
    WHERE  matDescription LIKE @Description 
    ORDER BY Isarchived, matRef 

1 个答案:

答案 0 :(得分:1)

这里的技巧是'WHERE matDescription LIKE @Description'不是真正的过滤器。 真正的过滤器是“ TOP 100”和“ ORDER BY Isarchived,matRef”一起使用,因为该过滤器将绝对过滤除100行以外的任何内容。 因此,您还需要在Isarchived和matRef处建立索引。 matRef的表扫描可能会延迟这一步。 同样,除非受约束,Isarchived,matRef组合是唯一的,否则最好在末尾添加PK,就像ORDER BY Isarchived,matRef,matid一样,这样挑选前100名就不会有其他问题。 最后,如果Isarchived类似于0/1,并且您有大量的记录,且值为0,则按顺序排序总是无用的,因为它始终为0。将其设置为过滤器Isarchived = 0并通过以下命令将其从订单中删除-使用matRef, matid并仅向matRef添加一个索引。