我正在使用inner join
运行查询。我用来进行聚合(SUM)的表上创建了索引,列名为dbo.tb_Sub_Contract.ContractGeneratedNo
。
任何表的最大行数约为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 :(得分: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
答案 1 :(得分: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