Java 使用服务器游标获取与流式获取之间的区别

Java 使用服务器游标获取与流式获取之间的区别,java,mysql,mysql-connector,Java,Mysql,Mysql Connector,从行为角度看,使用服务器游标获取结果和使用流媒体获取结果有什么区别 前者(服务器游标)可以通过以下方式激活: 通过在连接属性中设置和,对每个语句执行。(其中N是大于零的数字。) 或者通过在连接上初始设置useCursorFetch=true或com.mysql.jdbc.Connection.setUseCursorFetch(true)来执行单个语句,然后在语句上设置java.sql.Statement.setFetchSize(N) 后者()可以被激活: 通过设置java.sql.St

从行为角度看,使用服务器游标获取结果和使用流媒体获取结果有什么区别

前者(服务器游标)可以通过以下方式激活:

  • 通过在连接属性中设置和,对每个语句执行。(其中N是大于零的数字。)

  • 或者通过在连接上初始设置
    useCursorFetch=true
    com.mysql.jdbc.Connection.setUseCursorFetch(true)
    来执行单个语句,然后在语句上设置
    java.sql.Statement.setFetchSize(N)

后者()可以被激活:

  • 通过设置
    java.sql.Statement.setFetchSize(Integer.MIN_VALUE)
    或在语句上调用
    com.mysql.jdbc.Statement.enableStreamingResults()
    ,可以在单个语句上运行

  • 并且可能通过在连接属性中设置
    defaultFetchSize=X
    在每个语句上执行,其中X是一个等于
    Integer.MIN\u值的数字


<强>当使用这些替代方法开发时需要考虑什么?< /强>一个好的答案可能涉及性能、锁保持和资源分配(/分配)等主题。

< P>检查MySQL的连接器/J源代码(V5.1.39):

使用服务器游标(
setUseCursorFetch(true)
)时,如果结果集类型为
type\u FORWARD\u ONLY
,则“流”模式似乎只是一种特殊情况,其中获取的块仅为一行:

////// RowDataCursor.java /////////

private void fetchMoreRows() throws SQLException {
    ...

    synchronized (this.owner.connection.getConnectionMutex()) {
        ...

        int numRowsToFetch = this.owner.getFetchSize();
        ...

        if (numRowsToFetch == Integer.MIN_VALUE) {
            // Handle the case where the user used 'old' streaming result sets

            numRowsToFetch = 1;
        }
另请参见
MysqlIO.java
,了解实例化
RowDataCursor
的条件:

    //
    // Handle cursor-based fetch first
    //

    if (this.connection.versionMeetsMinimum(5, 0, 2) && this.connection.getUseCursorFetch() && isBinaryEncoded && callingStatement != null
            && callingStatement.getFetchSize() != 0 && callingStatement.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
        ServerPreparedStatement prepStmt = (com.mysql.jdbc.ServerPreparedStatement) callingStatement;

        boolean usingCursor = true;
MySQL 5.7文档表明,使用服务器游标在服务器端生成一个临时表(内存表,如果大小允许),因此这可能会影响服务器性能