在大表查询

时间:2018-04-19 17:14:24

标签: sql sql-server query-performance

我的这个表有大约500万行

CREATE TABLE [dbo].[Zip](
    [Coun_Code] [char](2) NOT NULL,
    [Zip] [varchar](10) NOT NULL,
    [State] [nvarchar](50) NOT NULL,
    [Zip_Name] [nvarchar](50) NOT NULL,
    [Active] [bit] NOT NULL,
 CONSTRAINT [Zip_Pk] PRIMARY KEY CLUSTERED 
(
    [Zip] ASC,
    [Coun_Code] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

有人可以帮我理解为什么第二个查询只需要两秒钟,而第一个查询需要大约9秒?我发现了复制粘贴错误......

Q1:没有联盟

DECLARE 
    @Filter nvarchar(50),
    @StartIndex int,
    @EndIndex int,
    @OnlyStartsWith bit

SELECT @Filter = 'c1210',
@StartIndex = 0,
@EndIndex = 100,
@OnlyStartsWith = 0

    IF @OnlyStartsWith = 1
        SET @Filter = @Filter + '%';
    ELSE
        SET @Filter = '%' + @Filter + '%';

    DECLARE @ZipFilter varchar(10) = @Filter;

    WITH NumberedZips AS
    (
         SELECT Zip, Zip_Name, Coun_Code, [State], Active, ROW_NUMBER() OVER (ORDER BY ZIP) as rowNum
         FROM 
            (
            SELECT Zip, Zip_Name, Coun_Code, [State], Active 
            FROM Zip z
            WHERE
                z.Zip LIKE @ZipFilter OR z.Zip_Name LIKE @Filter
            --UNION
            --SELECT Zip, Zip_Name, Coun_Code, [State], Active
            --FROM Zip z
            --WHERE
            --  z.Zip LIKE @ZipFilter OR z.Zip_Name LIKE @Filter
        ) filteredZips      
    )
    SELECT 
        COUN_CODE,
        ZIP_NAME,
        ZIP,
        Active,
        [State]
    FROM NumberedZips nz
    WHERE 
        rowNum BETWEEN @StartIndex AND @EndIndex

Q1 Execution plan

Q2:联盟

DECLARE 
    @Filter nvarchar(50),
    @StartIndex int,
    @EndIndex int,
    @OnlyStartsWith bit

SELECT @Filter = 'c1210',
@StartIndex = 0,
@EndIndex = 100,
@OnlyStartsWith = 0

    IF @OnlyStartsWith = 1
        SET @Filter = @Filter + '%';
    ELSE
        SET @Filter = '%' + @Filter + '%';

    DECLARE @ZipFilter varchar(10) = @Filter;

    WITH NumberedZips AS
    (
         SELECT Zip, Zip_Name, Coun_Code, [State], Active, ROW_NUMBER() OVER (ORDER BY ZIP) as rowNum
         FROM 
            (
            SELECT Zip, Zip_Name, Coun_Code, [State], Active 
            FROM Zip z
            WHERE
                z.Zip LIKE @ZipFilter OR z.Zip_Name LIKE @Filter
            UNION
            SELECT Zip, Zip_Name, Coun_Code, [State], Active
            FROM Zip z
            WHERE
                z.Zip LIKE @ZipFilter OR z.Zip_Name LIKE @Filter
        ) filteredZips      
    )
    SELECT 
        COUN_CODE,
        ZIP_NAME,
        ZIP,
        Active,
        [State]
    FROM NumberedZips nz
    WHERE 
        rowNum BETWEEN @StartIndex AND @EndIndex

Q2 Execution plan

据我所知,他们使用相同的索引。在嵌套的SELECT语句中删除任何一个过滤器都没有帮助/工作,那么它也需要大约9秒。我也尝试在Zip_Name上添加索引,但这也没有什么区别。

1 个答案:

答案 0 :(得分:0)

我没有解释为什么第二个会更快。 试试这个:

WITH NumberedZips AS
(
     SELECT Zip, Zip_Name, Coun_Code, [State], Active
          , ROW_NUMBER() OVER (ORDER BY ZIP) as rowNum
     FROM 
     (  SELECT Zip, Zip_Name, Coun_Code, [State], Active 
          FROM Zip z
         WHERE z.Zip LIKE @ZipFilter
        UNION
        SELECT Zip, Zip_Name, Coun_Code, [State], Active
          FROM Zip z
         WHERE z.Zip_Name LIKE @Filter
    ) filteredZips      
)
SELECT COUN_CODE, ZIP_NAME, ZIP, Active, [State]
  FROM NumberedZips nz
 WHERE rowNum BETWEEN @StartIndex AND @EndIndex