我有一个表格,其中包含一个分层的位置列表。位置具有父位置,并且位置具有多个兄弟位置。
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毫秒左右。下面是添加索引后更新的查询执行计划。
答案 0 :(得分:5)
由于您的ParentID
条件和WHERE
条件,您需要JOIN
上的索引。
之后,您可以尝试将所有列添加为"包含的列"在parent_id索引上。这意味着它甚至不必对聚集索引进行搜索。
CREATE INDEX ix_location_parentids
ON Location (ParentID)
INCLUDE (ParentID, ID, Description, Level)