如何加速多次左外连接,

时间:2014-06-23 09:42:59

标签: sql-server left-join

这是MS-SQL查询

我使用了许多左内连接。

NumberOfRow =约300,000行

结果时间约为4秒。

如何加快查询速度?。

PK是Id,Indexed RegionID

DECLARE @Location TABLE
        (
        Id int IDENTITY(1,1) PRIMARY KEY not null,
        RegionID int ,
        RegionType int ,
        SubClass int ,
        RegionName nvarchar(255) ,
        RegionNameLong nvarchar(512) ,
        ParentRegionID int
)

INSERT INTO @Location (RegionID, RegionType, SubClass, RegionName, RegionNameLong, ParentRegionID)
SELECT ORIGIN.RegionID AS RegionID
    ,ORIGIN.RegionType AS RegionType
    ,ORIGIN.SubClass AS SubClass
    ,REFER.RegionName AS RegionName
    ,REFER.RegionNameLong AS RegionNameLong
    ,ORIGIN.ParentRegionID AS ParentRegionID
FROM Location_en_US AS ORIGIN
    INNER JOIN Location_ko_KR AS REFER ON ORIGIN.RegionID = REFER.RegionID

SELECT
    TOP 10
    EN_1.RegionID, EN_1.RegionName, EN_2.RegionID, EN_2.RegionName, EN_3.RegionID, EN_3.RegionName, EN_4.RegionID, EN_4.RegionName, EN_5.RegionID, EN_5.RegionName, EN_6.RegionID, EN_6.RegionName
FROM @Location      AS EN_1
    LEFT OUTER JOIN @Location AS EN_2 ON EN_1.ParentRegionID = EN_2.RegionID
    LEFT OUTER JOIN @Location AS EN_3 ON EN_2.ParentRegionID = EN_3.RegionID
    LEFT OUTER JOIN @Location AS EN_4 ON EN_3.ParentRegionID = EN_4.RegionID
    LEFT OUTER JOIN @Location AS EN_5 ON EN_4.ParentRegionID = EN_5.RegionID
    LEFT OUTER JOIN @Location AS EN_6 ON EN_5.ParentRegionID = EN_6.RegionID
    INNER JOIN RegionType       AS RT ON EN_1.RegionType = RT.TypeCode AND RT.LanguageCode = 'en_US'
    INNER JOIN SubClass         AS SC ON EN_1.SubClass = SC.TypeCode  AND SC.LanguageCode = 'en_US'
WHERE   EN_1.RegionNameLong LIKE '%SEUOL%'

这是使用hierarchyid,但是最低的是左外连接

CREATE TABLE dbo.Location_en_US(
    Id int IDENTITY(1,1) PRIMARY KEY NOT NULL,
    Level hierarchyid NOT NULL,
    RegionID int NOT NULL,
    RegionType int NOT NULL,
    RelativeSignificance nvarchar(3) NULL,
    SubClass int NULL,
    RegionName nvarchar(255) NOT NULL,
    RegionNameLong nvarchar(512) NOT NULL,
    ParentRegionID int NULL,
    CreatedAt datetime2 NULL DEFAULT (getdate()),
)

SELECT RegionName AS RegionName1, 
(SELECT RegionName FROM Location_en_US WHERE Level = Location.Level.GetAncestor(1)) AS Level2,
(SELECT RegionName FROM Location_en_US WHERE Level = Location.Level.GetAncestor(2)) AS Level3,
(SELECT RegionName FROM Location_en_US WHERE Level = Location.Level.GetAncestor(3)) AS Level4,
(SELECT RegionName FROM Location_en_US WHERE Level = Location.Level.GetAncestor(4)) AS Level5,
(SELECT RegionName FROM Location_en_US WHERE Level = Location.Level.GetAncestor(5)) AS Level6
 FROM Location_en_US AS Location  WHERE RegionNameLong LIKE '%SEOUL%'

3 个答案:

答案 0 :(得分:1)

应该使用HierarhyId tecnique来操作树状结构。

ParentRegionID, RegionID列构建索引。

此外,没有列出的连接表被选中以查询结果集。

祝福!

答案 1 :(得分:0)

您已加入ParentRegionIDRegionID。任何一列的索引都可能有所帮助。在添加索引之前,您可能必须从表变量@Location切换到临时表#Location

添加索引后,检查"查询计划"从查询菜单中查看这有何帮助。

答案 2 :(得分:0)

regionId上添加索引。

您无法将索引显式添加到表变量中,因此请使用此技巧:

DECLARE @Location TABLE
        (
        Id int IDENTITY(1,1) PRIMARY KEY not null,
        RegionID int ,
        RegionType int ,
        SubClass int ,
        RegionName nvarchar(255) ,
        RegionNameLong nvarchar(512) ,
        ParentRegionID int,
        UNIQUE  (regionId, id)
        )

此外,您的左连接除了可能乘以相同记录外不会执行任何操作。你确定你的查询是正确的吗?