选择分组需要很长时间

时间:2015-10-01 16:38:35

标签: sql sql-server tsql sql-server-2008-r2 database-performance

我从表中选择时遇到问题。我正在运行以下查询:

DECLARE @FactId nvarchar (MAX)

set @FactId = '2379233,2379237,2379244,2379246,2379249,2379250,2379254,2379255,2379257,2379260,2379262,2379264,2379266,2379268,2379270,2379276,2379279,2379284,2379285,2379293,2379294,2379298,2379300,2379305,2379308,2379310,2379313';

BEGIN

SELECT  
    (apd.USS) as USS, (apd.Area) as Area, P.[Description] 
FROM
    [gisoo].AdministrationPileDetail apd
INNER JOIN 
    [gisoo].Locality L on L.LocalityId = apd.LocalityId
INNER JOIN 
    [gisoo].Province P on P.CountryId = L.CountryId AND P.Provinceid = L.ProvinceId
WHERE 
    apd.FactId IN (SELECT * FROM  [gisoo].[ItemListToTable](@FactId))
    AND L.ProvinceId IS NOT NULL
    AND L.DepartmentId IS NOT NULL
END
GO

此选择将nvarchar@FactId)划分为一个包含所有分隔ID的表格:

SELECT * 
FROM  [gisoo].[ItemListToTable](@FactId)

查询有12000行,需要两秒钟,但是当我运行该组需要40秒时。

DECLARE @FactId nvarchar (MAX)

set @FactId = '2379233,2379237,2379244,2379246,2379249,2379250,2379254,2379255,2379257,2379260,2379262,2379264,2379266,2379268,2379270,2379276,2379279,2379284,2379285,2379293,2379294,2379298,2379300,2379305,2379308,2379310,2379313';

BEGIN

SELECT  
    SUM(apd.USS) AS USS, 
    SUM(apd.Area) AS Area, 
    P.[Description] 
FROM 
    [gisoo].AdministrationPileDetail apd
INNER JOIN 
    [gisoo].Locality L ON L.LocalityId = apd.LocalityId
INNER JOIN 
    [gisoo].Province P ON P.CountryId = L.CountryId AND P.Provinceid = L.ProvinceId
WHERE 
    apd.FactId IN (SELECT * FROM  [gisoo].[ItemListToTable](@FactId))
    AND L.ProvinceId IS NOT NULL 
    AND L.DepartmentId IS NOT NULL
GROUP BY 
    P.[Description]
END
GO

两个表都没有索引。

我正在使用SQL Server 2008 R2和查询它也在SQL Server 2012中进行了测试。

2 个答案:

答案 0 :(得分:0)

试试这个 并用特定的列名

替换SELECT * FROM
set @FactId = '2379233,2379237,2379244,2379246,2379249,2379250,2379254,2379255,2379257,2379260,2379262,2379264,2379266,2379268,2379270,2379276,2379279,2379284,2379285,2379293,2379294,2379298,2379300,2379305,2379308,2379310,2379313';

BEGIN

SELECT SUM(apd.USS) AS USS, 
       SUM(apd.Area) AS Area, 
       P.[Description] 
  FROM [gisoo].AdministrationPileDetail apd
  JOIN [gisoo].Locality L 
        ON L.LocalityId = apd.LocalityId
       AND L.DepartmentId IS NOT NULL
       AND apd.FactId IN (SELECT * FROM  [gisoo].[ItemListToTable] (@FactId))          
  JOIN [gisoo].Province P 
        ON P.CountryId  = L.CountryId 
       AND P.Provinceid = L.ProvinceId          
 GROUP BY P.[Description]
END
GO

答案 1 :(得分:0)

对于您的查询,您应该索引以下内容:

CREATE INDEX IX_AdministrationPileDetail_LocalityId ON AdministrationPileDetail (LocalityID)
CREATE INDEX IX_AdministrationPileDetail_FactId ON AdministrationPileDetail (FactId)

CREATE INDEX IX_Locality_CountryId ON Locality(CountryId)
CREATE INDEX IX_Locality_ProvinceId ON Locality(ProvinceId)
CREATE INDEX IX_Locality_DepartmentId ON Locality(DepartmentId)

这是你的FK的基本索引,这是最好的做法。

然后,如果您仍然遇到问题,可以考虑在要分组的列中创建索引:

CREATE INDEX IX_Province_Description ON Province(Description)

您可能希望将该函数移到外部并为其创建时态表,而不是在WHERE上调用它。

SELECT 
   * 
INTO
   #Items
FROM  
   [gisoo].[ItemListToTable](@FactId)

CREATE IX_Items_FactId ON #Items(FactId)

SELECT  
    (apd.USS) as USS, (apd.Area) as Area, P.[Description] 
FROM
    [gisoo].AdministrationPileDetail apd
INNER JOIN 
    [gisoo].Locality L on L.LocalityId = apd.LocalityId
INNER JOIN 
    [gisoo].Province P on P.CountryId = L.CountryId AND P.Provinceid = L.ProvinceId
INNER JOIN
    #Items i ON apd.FactId = i.FactId
WHERE 
    apd.FactId IN (SELECT * FROM  [gisoo].[ItemListToTable](@FactId))
    AND L.ProvinceId IS NOT NULL
    AND L.DepartmentId IS NOT NULL