zoukankan      html  css  js  c++  java
  • SQL Server捕获发生The query processor ran out of internal resources and could not produce a query plan...错误的SQL语句

    最近收到一SQL Server数据库服务器的告警邮件,告警内容具体如下所示:

     

    DATE/TIME: 10/23/2018 4:30:26 PM

     

    DESCRIPTION:  The query processor ran out of internal resources and could not produce a query plan. This is a rare event and only expected for extremely complex queries or queries that reference a very large number of tables or partitions. Please simplify the query. If you believe you have received this message in error, contact Customer Support Services for more information.

     

     

    COMMENT:   (None)

     

    JOB RUN:   (None)

     

     

    关于8623 The query processor ran out of internal resources and could not produce a query plan”这个错误,这篇文章不分析错误产生的原因以及解决方案。这里仅仅介绍如何捕获产生这个错误的SQL语句。因为出现这个错误,具体对应的SQL语句不会写入到错误日志。不能定位到具体SQL语句,很难解决这错误。所以解决问题的前提是先定位SQL语句。我们可以通过扩展事件或服务器端跟踪两种方式来定位SQL语句。

     

     

    扩展事件(Extended Events)捕获

     

    如下所示,脚本只需根据实际情况修改filenamemetadatafile参数对应的值。就会创建扩展事件(Extented Events)overly_complex_queries

     

    CREATE EVENT SESSION
    overly_complex_queries
    ON SERVER
    ADD EVENT sqlserver.error_reported
    (
    ACTION (sqlserver.sql_text, sqlserver.tsql_stack, sqlserver.database_id, sqlserver.username)
    WHERE ([severity] = 16
    AND [error_number] = 8623)
    )
    ADD TARGET package0.asynchronous_file_target
    (set filename = 'D:DB_BACKUPoverly_complex_queries.xel' ,
    metadatafile = 'D:DB_BACKUPoverly_complex_queries.xem',
    max_file_size = 10,
    max_rollover_files = 5)
    WITH (MAX_DISPATCH_LATENCY = 5SECONDS)
    GO
    -- Start the session
    ALTER EVENT SESSION overly_complex_queries
    ON SERVER STATE = START
    GO

     

     

    然后我们测试,使用网上一个脚本测试验证,如下所示,执行这个脚本就会报8623 The query processor ran out of internal resources and could not produce a query plan”错误,如下所示:

     

     

    clip_image001

     

     

    选中扩展事件(Extented Events)overly_complex_queries,单击右键Watch Live Data"就能查看是那个SQL语句出现这个错误(sql_text),当然,也可以通过选项View Target Data查看所有捕获的数据。

     

     

    clip_image002

     

    注意:这个扩展事件只能运行在SQL Server 2012及后续版本,如果是SQL Server 2008的相关版本部署,就会报下面错误:

     

    Msg 25706, Level 16, State 8, Line 1

    The event attribute or predicate source, "error_number", could not be found.

    Msg 15151, Level 16, State 1, Line 18

    Cannot alter the event session 'overly_complex_queries', because it does not exist or you do not have permission.

     

     

     

    服务器端跟踪(Server Side Trace)捕获

     

     

    如上所示,刚好我们这台数据库服务器的版本为SQL Server 2008 R2,我们只能采取Server Side Trace来捕获这个错误的SQL语句。设置Server Side Trace脚本如下(相关参数需根据实际情况等设定):

     

    -- 定义参数  
    declare @rc int  
    declare @TraceID int  
    declare @maxfilesize bigint  
    set @maxfilesize = 1024   
     
    -- 初始化跟踪  
    exec @rc = sp_trace_create @TraceID output, 0, N'D:SQLScript	race_error_8623', @maxfilesize, NULL   
    --此处的D:SQLScript	race_error_8623是文件名(可自行修改),SQL会自动在后面加上.trc的扩展名  
    if (@rc != 0) goto error  
     
    -- 设置跟踪事件  
    declare @on bit  
    set @on = 1  
     
     
    --trace_event_id=13  SQL:BatchStarting   trace_event_id=22 ErrorLog
    exec sp_trace_setevent @TraceID, 13, 1,  @on    
    exec sp_trace_setevent @TraceID, 13, 3,  @on  
    exec sp_trace_setevent @TraceID, 13, 6,  @on  
    exec sp_trace_setevent @TraceID, 13, 7,  @on  
    exec sp_trace_setevent @TraceID, 13, 8,  @on  
    exec sp_trace_setevent @TraceID, 13, 11, @on  
    exec sp_trace_setevent @TraceID, 13, 12, @on 
    exec sp_trace_setevent @TraceID, 13, 14, @on 
    exec sp_trace_setevent @TraceID, 13, 15, @on 
    exec sp_trace_setevent @TraceID, 13, 35, @on  
    exec sp_trace_setevent @TraceID, 13, 63, @on  
     
    exec sp_trace_setevent @TraceID, 22, 1,  @on    
    exec sp_trace_setevent @TraceID, 22, 3,  @on  
    exec sp_trace_setevent @TraceID, 22, 6,  @on  
    exec sp_trace_setevent @TraceID, 22, 7,  @on  
    exec sp_trace_setevent @TraceID, 22, 8,  @on  
    exec sp_trace_setevent @TraceID, 22, 12, @on 
    exec sp_trace_setevent @TraceID, 22, 11, @on  
    exec sp_trace_setevent @TraceID, 22, 14, @on 
    exec sp_trace_setevent @TraceID, 22, 14, @on 
    exec sp_trace_setevent @TraceID, 22, 35, @on  
    exec sp_trace_setevent @TraceID, 22, 63, @on  
    -- 启动跟踪  
    exec sp_trace_setstatus @TraceID, 1  
     
    -- 记录下跟踪ID,以备后面使用  
    select TraceID = @TraceID  
    goto finish  
     
    error:   
    select ErrorCode=@rc  
     
    finish:   
    GO  

     

    上面SQL会生成一个服务器端跟踪事件,并返回对应的id,如下查看所示:

     

     

    clip_image003

     

    注意:上面捕获SQL:BatchStarting事件(trace_event_id=13),是因为捕获ErrorLogtrace_event_id=22)等事件时,都

    无法捕获到对应的SQL(对应的trace column没有捕获SQL语句,暂时还没有找到一个好的解决方法)。这里也有个弊端,就是会捕获大量无关的SQL语句

     

     

    测试过后,你可以使用SQL Profile工具打开D:SQLScript race_error_8623.trc找到错误信息,对应的SQL语句(在这个时间点附近的SQL语句,一般为是错误信息后面的第一个SQL语句,需要做判断),如下截图所示:

     

     

    clip_image004

     

     

    也可以使用脚本查询,如下所示,也是需要自己判断定位SQL语句,一般都是8623 The query processor ran out of internal resources and could not produce a query plan出现后紧接着的SQL。

     

     

    SELECT StartTime,EndTime,
        TextData, ApplicationName,SPID,Duration,LoginName
    FROM ::fn_trace_gettable(N'D:SQLScript	race_error_8623.trc',DEFAULT)
    WHERE spid=64
    ORDER BY StartTime

     

    clip_image005

     

     

     

     

    参考资料:

     

    https://www.mssqltips.com/sqlservertip/5279/sql-server-error-query-processor-ran-out-of-internal-resources-and-could-not-produce-a-query-plan/

    https://www.mssqltips.com/sqlservertip/1035/sql-server-performance-statistics-using-a-server-side-trace/

  • 相关阅读:
    ArrayList removeRange方法分析
    LinkedHashMap源码分析(基于JDK1.6)
    LinkedList原码分析(基于JDK1.6)
    TreeMap源码分析——深入分析(基于JDK1.6)
    51NOD 2072 装箱问题 背包问题 01 背包 DP 动态规划
    51 NOD 1049 最大子段和 动态规划 模板 板子 DP
    51NOD 1006 最长公共子序列 Lcs 动态规划 DP 模板题 板子
    8月20日 训练日记
    CodeForces
    CodeForces
  • 原文地址:https://www.cnblogs.com/kerrycode/p/9860653.html
Copyright © 2011-2022 走看看