2014-02-20 132 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