2014-02-20 159 views
2

我在使用inner join運行查詢。用於執行聚合(SUM)的表具有在其上創建的索引,其列名稱爲dbo.tb_Sub_Contract.ContractGeneratedNo如何減少sql server查詢時間

任何表的最大行數大約爲250條記錄。查詢需要很長時間才能執行,我怎樣才能縮短執行時間?

SELECT 
    dbo.tb_Sub_Contract.ContractGeneratedNo, 
    SUM(dbo.tb_Sub_Contract.GrossAmount) AS GrossTotalAmount, 
    SUM(dbo.tb_Sub_Contract.WithheldAmount) AS WithheldTotalAmount, 
    dbo.tb_General_Contract.FilingMonth, 
    dbo.tb_General_Contract.FromSequenceNo, 
    dbo.tb_General_Contract.BoxNo, 
    CAST(dbo.tb_General_Contract.CompanyTRN AS Varchar(20)) + '-' + CAST(ISNULL(dbo.tb_General_Contract.CompanyBranch, '') AS Varchar(2)) AS Company_TRN_Branch, 
    COUNT(dbo.tb_Sub_Contract.SubContractId) AS NumberofContractors, 
    dbo.Get_Company_Name(CAST(dbo.tb_General_Contract.CompanyTRN AS Varchar(20)) + '-' + CAST(ISNULL(dbo.tb_General_Contract.CompanyBranch, '') AS Varchar(2))) AS Taxpayer_Name, 
    dbo.tb_General_Contract.PostedDate, 
    dbo.tb_Station.Collectorate, 
    dbo.tb_Station.StationCode 
FROM   
    dbo.tb_General_Contract 
INNER JOIN 
    dbo.tb_Sub_Contract ON dbo.tb_General_Contract.ContractGeneratedNo = dbo.tb_Sub_Contract.ContractGeneratedNo 
INNER JOIN 
    dbo.tb_Station ON dbo.tb_General_Contract.StationId = dbo.tb_Station.StationCode 
WHERE  
    (dbo.tb_Sub_Contract.IsActive = 1) AND (dbo.tb_General_Contract.IsActive = 1) 
GROUP BY 
    dbo.tb_Sub_Contract.ContractGeneratedNo, dbo.tb_General_Contract.FilingMonth, 
    dbo.tb_General_Contract.FromSequenceNo, dbo.tb_General_Contract.BoxNo, 
    dbo.tb_General_Contract.CompanyTRN, dbo.tb_General_Contract.CompanyBranch, 
    dbo.tb_General_Contract.PostedDate, dbo.tb_Station.Collectorate, 
    dbo.tb_Station.StationCode 

見表的兩個表結構下面聚集

CREATE TABLE [dbo].[tb_Sub_Contract](
    [SubContractId] [bigint] IDENTITY(1,1) NOT NULL, 
    [ContractGeneratedNo] [varchar](100) NOT NULL, 
    [ContractTypeId] [int] NOT NULL, 
    [SubContractorName] [varchar](255) NOT NULL, 
    [PeriodBegin] [datetime] NOT NULL, 
    [PeriodEnd] [datetime] NOT NULL, 
    [GrossAmount] [decimal](14, 2) NOT NULL, 
    [WithheldAmount] [decimal](14, 2) NOT NULL, 
    [WithheldAmount_Cal] [decimal](14, 2) NOT NULL, 
    [trn_nbr] [bigint] NULL, 
    [ActionTakenId] [int] NULL, 
    [PostedBy] [bigint] NULL, 
    [PostedDate] [datetime] NULL, 
    [ModifiedBy] [bigint] NULL, 
    [ModificationDate] [datetime] NULL, 
    [IsActive] [bit] NULL, 
    [trn_nbrBranch] [smallint] NULL, 
CONSTRAINT [PK_tb_Sub_Contract] PRIMARY KEY CLUSTERED 
(
    [SubContractId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

CREATE TABLE [dbo].[tb_General_Contract](
    [ContractId] [bigint] IDENTITY(1,1) NOT NULL, 
    [ContractGeneratedNo] [varchar](100) NULL, 
    [CompanyTRN] [bigint] NULL, 
    [CompanyBranch] [smallint] NULL, 
    [FilingMonth] [datetime] NULL, 
    [FromSequenceNo] [varchar](50) NULL, 
    [BoxNo] [varchar](50) NULL, 
    [ActionTakenId] [int] NULL, 
    [PostedBy] [bigint] NULL, 
    [PostedDate] [datetime] NULL, 
    [IsActive] [bit] NULL, 
    [ModifiedBy] [bigint] NULL, 
    [ModificationDate] [datetime] NULL, 
    [StationId] [char](3) NULL, 
    [StationIdFrom] [char](3) NULL, 
CONSTRAINT [PK_tb_General_Contract] PRIMARY KEY CLUSTERED 
(
    [ContractId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
+0

你有什麼指標? –

+0

如果按CTRL-L(顯示計劃),查詢的最大貢獻者(百分比)是多少? –

回答

0

可以大大減少減少查詢時間該組按列。這可以通過分組由ContractGeneratedNo的tb_Sub_Contract聚集,然後加入該數據集的tb_General_Contract表來完成:

select 
    sc.ContractGeneratedNo, 
    sc.GrossTotalAmount, 
    sc.WithheldTotalAmount, 
    gc.FilingMonth, 
    gc.FromSequenceNo, 
    gc.BoxNo, 
    cast(gc.CompanyTRN as varchar(20)) + '-' + cast(isnull(gc.CompanyBranch, '') as varchar(2)) Company_TRN_Branch, 
    sc.NumberofContractors, 
    dbo.Get_Company_Name(cast(gc.CompanyTRN as varchar(20)) + '-' + cast(isnull(gc.CompanyBranch, '') as varchar(2))) as Taxpayer_Name, 
    gc.PostedDate, 
    s.Collectorate, 
    s.StationCode 
from dbo.tb_General_Contract gc 
    inner join (
       select 
        ContractGeneratedNo, 
        sum(GrossAmount) GrossTotalAmount, 
        sum(WithheldAmount) WithheldTotalAmount, 
        count(SubContractId) NumberofContractors 
       from dbo.tb_Sub_Contract 
       where IsActive = 1 
       group by 
        ContractGeneratedNo 
       ) sc 
     on gc.ContractGeneratedNo = sc.ContractGeneratedNo 
    inner join dbo.tb_Station 
     on gc.StationId = s.StationCode 
where 
    gc.IsActive = 1 
2

使用表的別名將使你的查詢更容易閱讀使用。

爲連接和過濾中使用的字段添加索引(WHERE子句)將大大提高性能。

有許多資源用於設計指標,如:SQL Server Index Guide

示例語法:

CREATE CLUSTERED INDEX idx_ContractGeneratedNo ON tb_General_Contract (ContractGeneratedNo) 
CREATE NONCLUSTERED INDEX idx_station ON tb_General_Contract (StationID) 
.... 

這裏有一個格式化的建議:

SELECT SC.ContractGeneratedNo 
     , SUM(SC.GrossAmount) AS GrossTotalAmount 
     , SUM(SC.WithheldAmount) AS WithheldTotalAmount 
     , GC.FilingMonth 
     , GC.FromSequenceNo 
     , GC.BoxNo 
     , CAST(GC.CompanyTRN AS VARCHAR(20)) + '-'+ CAST(ISNULL(GC.CompanyBranch, '') AS VARCHAR(2)) AS Company_TRN_Branch 
     , COUNT(SC.SubContractId) AS NumberofContractors 
     , Get_Company_Name(CAST(GC.CompanyTRN AS VARCHAR(20))+ '-'+ CAST(ISNULL(GC.CompanyBranch,'') AS VARCHAR(2))) AS Taxpayer_Name 
     , GC.PostedDate 
     , S.Collectorate 
     , S.StationCode 
FROM tb_General_Contract GC 
INNER JOIN tb_Sub_Contract SC 
    ON GC.ContractGeneratedNo = SC.ContractGeneratedNo 
INNER JOIN tb_Station S 
    ON GC.StationId = S.StationCode 
WHERE (SC.IsActive = 1) 
     AND (GC.IsActive = 1) 
GROUP BY SC.ContractGeneratedNo 
     , GC.FilingMonth 
     , GC.FromSequenceNo 
     , GC.BoxNo 
     , GC.CompanyTRN 
     , GC.CompanyBranch 
     , GC.PostedDate 
     , S.Collectorate 
     , S.StationCode