Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查询自联接表似乎很慢_Sql_Sql Server - Fatal编程技术网

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所做的。但是它使用了大量内存。。。