0

我正在尝试优化此查询。对于如何在估计的执行计划中降低估计的子树成本,我有点难过。结果通常平均返回 50k 行,并且花费的时间比我想要的要长。任何时间刮胡子都会很有用。谢谢。

SELECT
    tbl1.DID AS "CID",
    tbl1.ID AS "ID",

    tbl2.Column2 AS "Col2",
    tbl2.Column3 AS "Col3",

    tbl3.Column4 AS "Col4",
    tbl3.Column5 AS "Col5",

    tbl4.Column6 AS "Col6"
FROM TABLE1 tbl1 WITH (NOLOCK)
INNER JOIN TABLE2 tbl2 WITH (NOLOCK) ON tbl1.ID = tbl2.CID
INNER JOIN TABLE3 tbl3 WITH (NOLOCK) ON tbl1.ID = tbl3.CID 
INNER JOIN TABLE4 tbl4 WITH (NOLOCK) ON tbl1.DID = tbl4.CID

更新 - 主键信息。每个表的内部连接中的所有列都已经有索引。如果是主键,那么它看起来像下面的那个,否则它是一个非集群的,就像底部的那个。:主键索引看起来像这样。

ALTER TABLE [dbo].[IDX_TABLE1] ADD  CONSTRAINT [PK_TABLE1] PRIMARY KEY CLUSTERED 
(
[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF,      IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON  [PRIMARY]

非聚集的其他列索引如下所示:

CREATE NONCLUSTERED INDEX [IDX_TABLE1] ON [dbo].[TABLE1] 
(
[DID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON,    ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

表定义:

CREATE TABLE [dbo].[TABLE1](
[ID] [int] IDENTITY(1,1) NOT NULL,
[DID] [int] NULL
CONSTRAINT [PK_TABLE1] PRIMARY KEY CLUSTERED 
(
[ID] 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].[TABLE2](
[CID] [int] NOT NULL,
[Column3] [varchar](50) NULL,

 CONSTRAINT [PK_TABLE2] PRIMARY KEY CLUSTERED 
(
[CID] 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].[TABLE3](
[CID] [int] NOT NULL,
[Column4] [varchar](50) NULL
    [Column5] [varchar](50) NULL
CONSTRAINT [PK_TABLE3] PRIMARY KEY CLUSTERED 
(
[CID] 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].[TABLE4](
[CID] [int] NOT NULL,
[Column6] [char](2) NULL
CONSTRAINT [PK_TABLE4] PRIMARY KEY CLUSTERED 
(
[CID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,   ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
4

2 回答 2

4

确保每个表的连接列上都有索引。在 SQL Server 中,您还可以使用 INCLUDE 选项创建“覆盖索引”,并将查询中使用的所有列放在那里。这样,只有索引被读取,查询永远不会去表中获取数据。

像这样:

create index idx_name
on tbl2 (cid)
include (Column2, Column3)

根据附加信息,您需要 tbl2 上的索引和 tbl3 上与上述类似的索引。

create index idx_name1
on tbl3 (cid)
include (Column4, Column5)

这应该有助于一些性能。

于 2013-08-21T15:54:31.717 回答
2

根据您提供的信息,解决此问题的正确方法是选择整个查询,右键单击该选择,然后选择“Analyze Query in Database Engine Tuning Advisor”。它会给你一些关于如何优化它的想法。

如果不了解架构、执行计划当前运行时间,我们就无法优化这一点。我们还需要了解它所运行的硬件。

一般来说,调优顾问会让您深入了解可以对基础架构进行哪些更改以产生更快的结果。它还会告诉您应该看到多少改进(例如 98%)。

于 2013-08-21T15:42:59.923 回答