【问题标题】:Recommended index and query improvement推荐的索引和查询改进
【发布时间】:2019-04-19 19:45:36
【问题描述】:

我有这个跨服务器查询,它将大量行从我们的日志数据库插入到我们的数据仓库。问题是现在这项工作已经运行了 15 个小时以上。需要大幅度减少这种情况。需要有关此查询的最佳索引的建议,或者是否可以对查询本身进行任何改进。我正在考虑一个关于 URL 的索引,用于 fromDatabase 的时间戳和用于 toDatabase 的 ID 时间戳。但不确定关键列的最佳顺序,或者我是否应该使用包含等。非常感谢所有帮助。

  SELECT @SQL = N'
    INSERT INTO ' + @ToDatabase + '.dbo.Log
        (
        ImportDateTime
        ,ServerSource
        ,DatabaseSource
        ,Id
        ,Type
        ,UserName
        ,AppCode                        
        ,SubscriptionCode
        ,Duration
        ,ServiceNamespace
        ,ServiceName
        ,MethodName
        ,Parameters
        ,[Message]
        ,StackTrace
        ,Url
        ,UrlReferrer
        ,Browser
        ,BrowserVersion
        ,Platform
        ,Timestamp
        ,IpAddress
        ,EriAccountId
        )
        (
            SELECT
            ''' +  CONVERT(VARCHAR(50),@ImportDateTime) + '''
            ,''' +  @ServerSource + '''
            ,''' +  @DatabaseSource + '''
            ,Id
            ,Type
            ,UserName
            ,AppCode
            ,SubscriptionCode
            ,Duration
            ,ServiceNamespace
            ,ServiceName
            ,MethodName
            ,Parameters
            ,Message
            ,StackTrace
            ,Url
            ,UrlReferrer
            ,Browser
            ,BrowserVersion
            ,Platform
            ,Timestamp
            ,IpAddress
            ,EriAccountId

         FROM (
                select
                Id
                ,Type
                ,UserName
                ,AppCode
                ,SubscriptionCode
                ,Duration
                ,ServiceNamespace
                ,ServiceName
                ,MethodName
                ,Parameters
                ,Message
                ,StackTrace
                ,Url
                ,UrlReferrer
                ,Browser
                ,BrowserVersion
                ,Platform
                ,Timestamp
                ,IpAddress
                ,EriAccountId

    from openquery([' + @ServerSource + '],
                    ''select 
                    Id
                    ,Type
                    ,UserName
                    ,AppCode
                    ,SubscriptionCode
                    ,Duration
                    ,ServiceNamespace
                    ,ServiceName
                    ,MethodName
                    ,[Parameters] = CONVERT(NVARCHAR(MAX),[Parameters])
                    ,[Message]
                    ,StackTrace
                    ,Url
                    ,UrlReferrer
                    ,Browser
                    ,BrowserVersion
                    ,Platform
                    ,Timestamp
                    ,IpAddress
                    ,EriAccountId           
                    FROM ' + @FromDatabase + '.dbo.[Log] WITH (NOLOCK)
                    WHERE URL LIKE ''''http://online%'''' AND CONVERT(DATETIME2, TimeStamp) > ''''' + CONVERT(NVARCHAR(50),@AssessorDeploymentTimestamp) + ''''' AND CONVERT(DATETIME2,TimeStamp) > ''''' +  CONVERT(NVARCHAR(50),@DateCollected) + ''''' '') o
                    WHERE NOT EXISTS 
                        (SELECT 1
                        FROM ' + @ToDatabase + '.dbo.Log b 
                        WHERE b.id = o.id
                        AND CONVERT(DATETIME2, b.TimeStamp) > ''' +  CONVERT(NVARCHAR(50),@DateCollected) + '''
                        AND b.ServerSource = ''' +  @ServerSource + '''
                        )

                ) a
        )'

【问题讨论】:

    标签: sql performance tsql indexing sql-server-2014


    【解决方案1】:

    首先我要说的是,除了实施正确的索引策略之外,您还应该遵循一些优化查询执行时间的技巧。

    • 避免使用内部 SELECT 和 JOIN 语句中的函数。函数(即使是缓存的)应该针对尽可能少的记录执行,通常,这发生在最外层的选择中。
    • 尽可能避免子查询,而是选择 JOIN。
    • 尽可能避免在 where 语句中使用非数字字段,INT 字段的索引扫描比 VARCHAR 快得多。
    • 避免使用 WITH(NOLOCK) 提示,因为您还会读取未提交的数据。它不会使查询变得更快,而且您可能会有一个脏数据集。

    在尝试优化查询时,还要记住查询“解释器”用来解析它的操作顺序:

    1. 从和加入块
    2. 分组依据和拥有
    3. 在哪里
    4. 选择

    因此,请尝试编写您的查询以减少每个块按此顺序返回的数量或记录。

    话虽如此,必须根据使用的查询创建 INDEX,如果您测试包含执行计划的查询执行,您可以找到有用的提示,通常 SSMS 可以帮助您很多。

    在这种情况下,我将按顺序在 URLTimeStamp 字段上添加索引

    CREATE CLUSTERED INDEX idx_Log ON yourDatabase.dbo.[log] (URL, Timestamp)
    

    【讨论】:

      猜你喜欢
      • 2016-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-23
      • 1970-01-01
      • 2015-01-11
      • 2017-05-15
      • 2017-06-03
      相关资源
      最近更新 更多