Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.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 server QL可以考虑使用聚集索引比使用非聚集索引更便宜,然后查找簇索引中的每个匹配行的ActueID。这是因为相对于顺序I/O,聚集索引查找非常昂贵,因此任何需要查找超过百分之几的行的计划都可能比扫描更便宜。无论如何,如果这确实是您所看到的问题,那么在IX_STAT_Statistieken_1索引中添加actieGroep作为INCLUDE-d列应该可以解决这个问题。像这样:_Sql Server_Tsql_Indexing - Fatal编程技术网

Sql server QL可以考虑使用聚集索引比使用非聚集索引更便宜,然后查找簇索引中的每个匹配行的ActueID。这是因为相对于顺序I/O,聚集索引查找非常昂贵,因此任何需要查找超过百分之几的行的计划都可能比扫描更便宜。无论如何,如果这确实是您所看到的问题,那么在IX_STAT_Statistieken_1索引中添加actieGroep作为INCLUDE-d列应该可以解决这个问题。像这样:

Sql server QL可以考虑使用聚集索引比使用非聚集索引更便宜,然后查找簇索引中的每个匹配行的ActueID。这是因为相对于顺序I/O,聚集索引查找非常昂贵,因此任何需要查找超过百分之几的行的计划都可能比扫描更便宜。无论如何,如果这确实是您所看到的问题,那么在IX_STAT_Statistieken_1索引中添加actieGroep作为INCLUDE-d列应该可以解决这个问题。像这样:,sql-server,tsql,indexing,Sql Server,Tsql,Indexing,在[dbo].[STAT\u Statistieken]上创建非聚集索引[IX\u Statistieken\u 1] ( [外来]描述, [secondaryId]ASC, [actieGroep]ASC, [Dagnumer]描述, [aantal]ASC )在[PRIMARY]上包含(actieId) 计算列actieGroep的数据类型是一个字符串,但您正在将其与WHERE子句和CASE语句中的整数(例如(1,2,3))进行比较。如果SQL决定转换列而不是常量,则会影响查询性能,并可能导

在[dbo].[STAT\u Statistieken]上创建非聚集索引[IX\u Statistieken\u 1]

[外来]描述,
[secondaryId]ASC,
[actieGroep]ASC,
[Dagnumer]描述,
[aantal]ASC
)在[PRIMARY]上包含(actieId)

  • 计算列actieGroep的数据类型是一个字符串,但您正在将其与WHERE子句和CASE语句中的整数(例如(1,2,3))进行比较。如果SQL决定转换列而不是常量,则会影响查询性能,并可能导致计算列扩展问题(如上所述)。我强烈建议将计算列定义更改为整数类型,例如

    当actieId介于0和9之间时,则actieId
    当actieId在10和99之间时,则actieId/10
    当激活ID在100和999之间时,则激活ID/100
    当激活ID介于1000和9999之间时,则激活ID/1000
    当激活ID介于10000和99999之间时,则激活ID/10000
    当激活ID介于100000和999999之间时,则激活ID/100000
    当激活ID介于1000000和9999999之间时,则激活ID/1000000
    其他活动ID/10000000结束

  • 您正在按只有一个可能值的列进行分组。因此,分组讨论是不必要的。希望优化器足够聪明,知道这一点,但您永远无法确定

  • 尝试使用OPTIMIZE FOR提示,而不是直接强制索引,这可能会解决提示中出现的错误

  • CraigFreedman的文章描述了在使用重新编译时收到的提示相关错误消息的常见原因。您可能希望查看该帖子,并确保正在运行对SQL Server的最新更新

  • 我相信您已经这样做了,但是您可能希望通过我们正在做的事情来构建数据的“洁净室”版本:创建一个新的数据库,使用问题中的DDL创建表,然后用数据填充表。如果得到的结果不同,请查看实际表和索引中的模式,看看它们是否不同

  • 如果这些都不管用,请发表评论,我可以提出一些更疯狂的想法。:-)

    另外,请在您的问题中添加SQL Server的确切版本和更新级别

    select AU.*
    FROM SYS.Allocation_units AS AU
    INNER JOIN SYS.Partitions AS P
    ON AU.Container_id = P.Partition_id
    WHERE Object_ID = object_id('STAT_Statistieken')
    

    尝试此操作并检查非聚集索引是否比聚集索引具有更多的页面(这意味着读取聚集索引更便宜)

    首先,我应该说您创建的索引不是最优的,因为它们只能用于过滤
    异化的

    SQL Server
    无法执行
    跳过扫描
    ,并且索引中有一个
    secondaryId
    ,未使用范围条件进行筛选

    因此,您在
    foreigned、actieGroep、dagNummer
    上的条件不会产生有限的范围,也不完全可销售。它只能对异化的进行过滤,不能对整个集合进行过滤

    现在,转到您当前的索引

    我刚刚创建了您的表,并使用以下脚本用随机数据填充它们:

    DROP TABLE STAT_Statistieken
    
    CREATE TABLE [dbo].[STAT_Statistieken](
        [statistiekId] [bigint] IDENTITY(1,1) NOT NULL,
        [foreignId] [bigint] NOT NULL,
        [datum] [datetime] NOT NULL, --date
        [websiteId] [int] NOT NULL,
        [actieId] [int] NOT NULL, --actionId
        [objectSoortId] [int] NOT NULL, --kindOfObjectId
        [aantal] [bigint] NOT NULL, --count
        [secondaryId] [int] NOT NULL DEFAULT ((0)),
        [dagnummer]  AS (datediff(day,CONVERT([datetime],'2009-01-01 00:00:00.000',(121)),[datum])) PERSISTED, --daynumber
        [actieGroep]  AS (substring(CONVERT([varchar](4),[actieId],0),(1),(1))) PERSISTED,
        CONSTRAINT [STAT_Statistieken_PK] PRIMARY KEY CLUSTERED --actionGroup
        (
            [statistiekId] ASC
        )WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
        ) ON [PRIMARY]
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_1] ON [dbo].[STAT_Statistieken] 
    (
        [foreignId] DESC,
        [secondaryId] ASC,
        [actieGroep] ASC,
        [dagnummer] DESC, 
        [aantal] ASC --count
    )WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF,  ONLINE = OFF) ON [PRIMARY]
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_2] ON [dbo].[STAT_Statistieken] 
    (
        [foreignId] DESC,
        [secondaryId] ASC,
        [actieId] ASC,
        [dagnummer] DESC,
        [aantal] ASC -- count
    )WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
    
    ;WITH    nums AS
            (
            SELECT  1 AS num
            UNION ALL
            SELECT  num + 1
            FROM    nums
            )
    INSERT
    INTO    STAT_Statistieken (
            [foreignId], [datum], [websiteId], [actieId],
            [objectSoortId], [aantal])
    SELECT  TOP 100000
            500, GETDATE(), num, num, num, num % 5
    FROM    nums
    UNION ALL
    SELECT  TOP 100000
            num % 1000, GETDATE(), num, num, num, num % 5
    FROM    nums
    OPTION (MAXRECURSION 0)
    
    UPDATE STATISTICS STAT_Statistieken
    
    ,它使用
    索引查找
    ,这很可能意味着问题出在数据分布上

    我建议您创建一个附加索引,删除
    secondaryID
    ,如下所示:

    ALTER PROCEDURE MyProcedure (@fid BIGINT)
    AS BEGIN
        DECLARE @fid_sniff BIGINT
        SET @fid_sniff=@fid
        SELECT foreignId
        FROM STAT_Statistieken
        WHERE foreignId = @fid_sniff
    END
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_1] ON [dbo].[STAT_Statistieken]  
    (  
        [foreignId] DESC,  
        [dagnummer] DESC,  
        [actieId] ASC,   
        [aantal] ASC    
    ) INCLUDE (datum)  ON [PRIMARY]
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_3] ON [dbo].[STAT_Statistieken] 
    (
        [foreignId] DESC,
        [actieGroep] ASC,
        [dagnummer] DESC, 
        [aantal] ASC --count
    )
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_2] ON [dbo].[STAT_Statistieken] 
    (
        [foreignId] DESC,
        [secondaryId] ASC,
        [actieId] ASC,
        [dagnummer] DESC,
        [aantal] ASC -- count
    )
    INCLUDE (actieGroep);       
    WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
    
    如果仍要使用当前索引,请运行以下命令:

    DBCC SHOW_STATISTICS ('STAT_Statistieken', 'IX_STAT_Statistieken_1')
    DBCC SHOW_STATISTICS ('STAT_Statistieken', 'IX_STAT_Statistieken_2')
    
    每个命令将输出三个结果集


    请您发布每个命令的结果集
    1
    2
    ,以及结果集
    3
    的三行,其值
    RANGE\u HI
    就在上面,就在下面,等于
    873926

    我以前见过类似的行为,它实际上会接受索引提示,并用它做更糟的事情(带书签查找的未筛选索引扫描)

    这四项中的一项应该有帮助:

    1) 附加-T4102-T4118到SQL Server 2005启动参数(可能适用于SQL 2008)。注意:这会导致SQL 2005中对IN和NOT IN查询的SQL 2000错误处理

    2) 使用FULLSCAN更新统计信息[dbo].[STAT\U Statistieken]

    3) 选项(MAXDOP 1)——有时并行性会导致生成非常愚蠢的查询

    4) 确保索引处于联机状态

    还请注意,如果要在存储过程中创建的表上创建索引,则在编译存储过程查询时该索引不存在,因此不会使用该索引。由于您的表是在dbo中全局创建的,所以我假设这里不是这样


    编辑:有时我希望有一个真正的forceplan,您可以直接输入计划并执行任何可能的计划:类似于DB的汇编语言。

    尝试创建如下索引:

    ALTER PROCEDURE MyProcedure (@fid BIGINT)
    AS BEGIN
        DECLARE @fid_sniff BIGINT
        SET @fid_sniff=@fid
        SELECT foreignId
        FROM STAT_Statistieken
        WHERE foreignId = @fid_sniff
    END
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_1] ON [dbo].[STAT_Statistieken]  
    (  
        [foreignId] DESC,  
        [dagnummer] DESC,  
        [actieId] ASC,   
        [aantal] ASC    
    ) INCLUDE (datum)  ON [PRIMARY]
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_3] ON [dbo].[STAT_Statistieken] 
    (
        [foreignId] DESC,
        [actieGroep] ASC,
        [dagnummer] DESC, 
        [aantal] ASC --count
    )
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_2] ON [dbo].[STAT_Statistieken] 
    (
        [foreignId] DESC,
        [secondaryId] ASC,
        [actieId] ASC,
        [dagnummer] DESC,
        [aantal] ASC -- count
    )
    INCLUDE (actieGroep);       
    WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
    

    然后重新创建您的过程

    是存储过程的重点,以确定是否存在从STAT_Statistieken到另一个表的链接,或者存在多少这样的链接?不,这只是问题的抽象版本。我只想使用索引对表进行选择。表中只包含一堆bigints@Jan:可能是一个没有实际意义的问题,但您是否更新了统计数据、整理了索引(最明显的是聚集索引)碎片?如果我用有限的信息模拟模式,我就不会遇到它期望的问题。关于查询缓存/查询计划命中/参数的问题
    select AU.*
    FROM SYS.Allocation_units AS AU
    INNER JOIN SYS.Partitions AS P
    ON AU.Container_id = P.Partition_id
    WHERE Object_ID = object_id('STAT_Statistieken')
    
    DROP TABLE STAT_Statistieken
    
    CREATE TABLE [dbo].[STAT_Statistieken](
        [statistiekId] [bigint] IDENTITY(1,1) NOT NULL,
        [foreignId] [bigint] NOT NULL,
        [datum] [datetime] NOT NULL, --date
        [websiteId] [int] NOT NULL,
        [actieId] [int] NOT NULL, --actionId
        [objectSoortId] [int] NOT NULL, --kindOfObjectId
        [aantal] [bigint] NOT NULL, --count
        [secondaryId] [int] NOT NULL DEFAULT ((0)),
        [dagnummer]  AS (datediff(day,CONVERT([datetime],'2009-01-01 00:00:00.000',(121)),[datum])) PERSISTED, --daynumber
        [actieGroep]  AS (substring(CONVERT([varchar](4),[actieId],0),(1),(1))) PERSISTED,
        CONSTRAINT [STAT_Statistieken_PK] PRIMARY KEY CLUSTERED --actionGroup
        (
            [statistiekId] ASC
        )WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
        ) ON [PRIMARY]
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_1] ON [dbo].[STAT_Statistieken] 
    (
        [foreignId] DESC,
        [secondaryId] ASC,
        [actieGroep] ASC,
        [dagnummer] DESC, 
        [aantal] ASC --count
    )WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF,  ONLINE = OFF) ON [PRIMARY]
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_2] ON [dbo].[STAT_Statistieken] 
    (
        [foreignId] DESC,
        [secondaryId] ASC,
        [actieId] ASC,
        [dagnummer] DESC,
        [aantal] ASC -- count
    )WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
    
    ;WITH    nums AS
            (
            SELECT  1 AS num
            UNION ALL
            SELECT  num + 1
            FROM    nums
            )
    INSERT
    INTO    STAT_Statistieken (
            [foreignId], [datum], [websiteId], [actieId],
            [objectSoortId], [aantal])
    SELECT  TOP 100000
            500, GETDATE(), num, num, num, num % 5
    FROM    nums
    UNION ALL
    SELECT  TOP 100000
            num % 1000, GETDATE(), num, num, num, num % 5
    FROM    nums
    OPTION (MAXRECURSION 0)
    
    UPDATE STATISTICS STAT_Statistieken
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_3] ON [dbo].[STAT_Statistieken] 
    (
        [foreignId] DESC,
        [actieGroep] ASC,
        [dagnummer] DESC, 
        [aantal] ASC --count
    )
    
    DBCC SHOW_STATISTICS ('STAT_Statistieken', 'IX_STAT_Statistieken_1')
    DBCC SHOW_STATISTICS ('STAT_Statistieken', 'IX_STAT_Statistieken_2')
    
    CREATE NONCLUSTERED INDEX [IX_STAT_Statistieken_2] ON [dbo].[STAT_Statistieken] 
    (
        [foreignId] DESC,
        [secondaryId] ASC,
        [actieId] ASC,
        [dagnummer] DESC,
        [aantal] ASC -- count
    )
    INCLUDE (actieGroep);       
    WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]