【问题标题】:Retrieve SQL Server query statistics through JDBC通过 JDBC 检索 SQL Server 查询统计信息
【发布时间】:2012-06-19 12:01:41
【问题描述】:

我想通过JDBC接口检索SQL Server在使用SET STATISTICS IO ON时返回的统计信息。

获取执行计划非常简单,因为在运行SET SHOWPLAN_XML ON 之后,调用Statement.execute() 的结果将是执行计划。使用 SET STATISTICS XML OFF 时,Statement 实例会返回第二个 ResultSet。

但是,在使用Statement.execute() 之前运行SET STATISTICS IO ON 时,只会返回查询结果。没有更多的结果集,没有任何警告。

有人知道我如何获得这些信息吗?它可能隐藏在哪里?

我尝试对 SQL Server 2005、SQL Server 2008R2 和 SQL Server 2012 使用 jTDS 以及 Microsoft 的 JDBC 驱动程序(3.0 和 4.0)。

我检查了查询返回的所有结果集(使用Statement.getMoreResults() 检查),以及Connection.getWarnings()Statement.getWarnings() 返回的警告对象。

【问题讨论】:

    标签: sql-server jdbc


    【解决方案1】:

    SET SHOWPLAN_XML ON 将任何后续语句的结果集更改为计划而不是查询结果相反,SET STATISTICS IO ON 不会。

    SET STATISTICS IO ON 让查询执行并将统计信息显示为消息。 见http://msdn.microsoft.com/en-us/library/ms131350.aspx

    在 ADO.NET 中,SqlConnection 对象上有一个名为 InfoMessage 的事件,您可以在该事件上插入一个处理程序并获取服务器显示的任何消息,例如打印或 IO 统计信息。

    我很快查看了 SQL Server 的 MS JDBC 驱动程序,但没有找到任何接近的东西,我发现最好的是:Is there a way to display PRINT results with SQL server JDBC driver?。 我的 Java 知识很薄弱,尽管 SQL Server 消息结果上的上述链接仅提及“SQL Server Native Client OLE DB 提供程序”,但其他驱动程序中可能存在类似的东西。


    多看之后,我发现您可以让消息运行跟踪(使用探查器),并且该消息显示为“用户错误消息”事件类下的跟踪消息,其中包含您可以使用的 TransactionID用于将其与您的批次相关联。

    在 SQL Server 的后台运行默认跟踪。 请参阅http://www.simple-talk.com/sql/performance/the-default-trace-in-sql-server---the-power-of-performance-and-security-auditing/http://www.sqlservercentral.com/articles/sql+server+2005/64547/,您可能会在跟踪中插入您需要的事件,或者运行另一个事件然后从中读取。

    说实话,希望你能找到更好的解决方案。

    编辑:

    我不知道为什么您可以使用 JDBC 函数获取打印消息但不能获取 IO 统计信息,但我可以按照我开始跟踪的方向提出其他建议。

    您可以使用扩展事件来做到这一点,在正确的事件上放置一个句柄,然后使用以下内容读取跟踪:

    首先在数据库上执行:

    CREATE EVENT SESSION QueryStats ON SERVER
    ADD EVENT sqlserver.error_reported
    (
        ACTION(sqlserver.sql_text)
        WHERE (severity = 10
            AND state = 0
            AND user_defined = 0
            AND error = 3615)
    )
    ADD TARGET package0.ring_buffer
    WITH(max_dispatch_latency = 1 seconds)
    GO
    

    然后围绕你的陈述:

    ALTER EVENT SESSION QueryStats ON SERVER STATE = START
    
    SET STATISTICS IO ON
    
    select * from MyTable -- your statement(s)
    
    SET STATISTICS IO OFF
    
    WAITFOR DELAY '00:00:01'; -- you have to wait because you can't set under 1 second of max_dispatch_latency 
    WITH QueryStats
    AS (
        SELECT CAST(target_data AS xml) AS SessionData
        FROM sys.dm_xe_session_targets st
            INNER JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address
        WHERE name = 'QueryStats'
    )
    SELECT
        error.value('(@timestamp)[1]', 'datetime') as event_timestamp
        ,error.value('(action/value)[1]', 'nvarchar(max)') as sql_text
        ,error.value('(data/value)[5]', 'varchar(max)') as [message]
    FROM QueryStats d 
        CROSS APPLY SessionData.nodes ('//RingBufferTarget/event') AS t(error)
    ALTER EVENT SESSION QueryStats ON SERVER STATE = STOP
    GO
    

    然后您将获得第二个包含 IO 统计信息的结果集。

    不过,解决方案远未最终确定,因为需要消除等待时间并更好地确定跟踪范围,这可能是可能的。 您还可以让跟踪运行并在以后及时获取所有语句/IO 统计信息,具体取决于您打算如何处理这些。

    【讨论】:

    • 感谢您的回答。使用PRINT“发送”的消息可以使用提到的Statement.getWarnings()Connection.getWarnings() 检索。我已经用它来获取这些信息。但它们都没有返回 IO 统计信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2015-06-01
    • 2013-09-03
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    相关资源
    最近更新 更多