Sql 查询自联接表似乎很慢
我有一个表,其中包含位置的分层列表。一个位置有一个父位置,而一个位置有多个同级Sql 查询自联接表似乎很慢,sql,sql-server,Sql,Sql Server,我有一个表,其中包含位置的分层列表。一个位置有一个父位置,而一个位置有多个同级 CREATE TABLE [dbo].[Location] ( [ID] [int] IDENTITY(1,1) NOT NULL, [ParentID] [int] NULL, [LocationTypeID] [int] NOT NULL, [Description] [varchar](100) NOT NULL, [Deleted] [datetime] NULL,
CREATE TABLE [dbo].[Location]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[ParentID] [int] NULL,
[LocationTypeID] [int] NOT NULL,
[Description] [varchar](100) NOT NULL,
[Deleted] [datetime] NULL,
[CreatedDate] [datetime] NOT NULL,
[CreatedUserID] [int] NOT NULL,
[ModifiedDate] [datetime] NULL,
[ModifiedUserID] [int] NULL,
[Version] [timestamp] NOT NULL,
CONSTRAINT [pk_location]
PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON)
)
GO
ALTER TABLE [dbo].[Location] WITH CHECK
ADD CONSTRAINT [fk_location_location]
FOREIGN KEY([ParentID]) REFERENCES [dbo].[Location] ([ID])
GO
查询数据时,我创建了一个视图以简化输出:
WITH MyLocation AS
(
SELECT
A.ParentID, A.ID,
Description,
0 AS 'Level',
CAST(A.Description AS VARCHAR(512)) AS SORT_PATH
FROM
Location A
WHERE
A.ParentID IS NULL
UNION ALL
SELECT
C.ParentID, C.ID,
C.Description,
Level + 1,
CAST(SORT_PATH + '//' + C.Description AS VARCHAR(512)) AS SORT_PATH
FROM
Location C
INNER JOIN
MyLocation ON MyLocation.ID = C.ParentID
)
SELECT
ParentID, ID, Level,
SORT_PATH,
ML.Description AS DISPLAY_PATH
FROM
MyLocation AS ML
但我从这个视图中选择,例如:
SELECT *
FROM MyView
WHERE ID = 367
我得到了大约400毫秒的响应时间,而这个表只有750行。这可能是因为查询需要查看全部数据,然后只选择我想要的项目,但速度似乎仍然有点慢
是否有一些索引可用于提高性能
以下是执行计划。聚集索引扫描成本高达55%。。。还有29%的连接发生了。可以通过添加索引来辅助这些操作吗?是否可以删除可空的“ParentID”(表示根)
我已使用以下代码在ParentID上添加了一个新索引:
CREATE INDEX ix_location_parentids
ON Location (ParentID)
平均执行时间减少了20毫秒,约为370毫秒。下面是添加索引后更新的查询执行计划
由于您的
WHERE
条件和您的JOIN
条件,您需要在ParentID
上建立索引
之后,您可以尝试将所有列添加为父索引上的“包含列”。这意味着它甚至不必对聚集索引进行搜索
CREATE INDEX ix_location_parentids
ON Location (ParentID)
INCLUDE (ParentID, ID, Description, Level)
您在ID或父\u ID上有索引吗?聚集索引(pk\u位置)是我当前在此表上唯一的索引。当我使用“CONSTRAINT pk_location PRIMARY KEY(ID)”创建表时,它默认创建为集群。单击连接节点查看它在做什么。它将提供一些看起来像SQL的提示。我打赌这就是你的
UNION-ALL
语句在ParentID
列上创建一个非聚集索引
,我试过了,平均每个查询缩短了20毫秒。查询从390毫秒左右变为370毫秒。@Craig创建索引后,你能发布执行计划吗。不是聚集索引扫描,而是聚集索引搜索。@Joe-您添加的包含索引已从370ms中获取。。到37毫秒!难以置信的谢谢你能解释一下你的想法吗,这样我就能理解这是如何实现如此惊人的性能改进的?因为你将MyLocation与Location结合起来,基本上包括了所有字段,所以直接将这些字段放在索引上就更容易了。这就是INCLUDE所做的。但是它使用了大量内存。。。