sql >> Base de Datos >  >> RDS >> Mysql

¿MySQL Connector/J almacena en búfer las filas cuando transmite un ResultSet?

Lo hace, al menos a veces. Probé el comportamiento de MySQL Connector/J versión 5.1.37 usando Wireshark. Para la mesa...

CREATE TABLE lorem (
    id INT AUTO_INCREMENT PRIMARY KEY,
    tag VARCHAR(7),
    text1 VARCHAR(255),
    text2 VARCHAR(255)
    )

... con datos de prueba ...

 id  tag      text1            text2
---  -------  ---------------  ---------------
  0  row_000  Lorem ipsum ...  Lorem ipsum ...
  1  row_001  Lorem ipsum ...  Lorem ipsum ...
  2  row_002  Lorem ipsum ...  Lorem ipsum ...
...
999  row_999  Lorem ipsum ...  Lorem ipsum ...

(where both `text1` and `text2` actually contain 255 characters in each row)

... y el código ...

try (Statement s = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY)) {
    s.setFetchSize(Integer.MIN_VALUE);
    String sql = "SELECT * FROM lorem ORDER BY id";
    try (ResultSet rs = s.executeQuery(sql)) {

... inmediatamente después de s.executeQuery(sql) – es decir, antes de rs.next() incluso se llama:MySQL Connector/J había recuperado las primeras ~140 filas de la tabla.

De hecho, al consultar solo la tag columna

    String sql = "SELECT tag FROM lorem ORDER BY id";

MySQL Connector/J recuperó inmediatamente las 1000 filas como se muestra en la lista de tramas de red de Wireshark:

El cuadro 19, que envió la consulta al servidor, se veía así:

El servidor MySQL respondió con el marco 20, que comenzó con ...

... y fue seguido inmediatamente por el cuadro 21, que comenzó con ...

... y así sucesivamente hasta que el servidor envió el cuadro 32, que terminó con

Dado que la única diferencia fue la cantidad de información que se devolvió para cada fila, podemos concluir que MySQL Connector/J decide un tamaño de búfer adecuado en función de la longitud máxima de cada fila devuelta y la cantidad de memoria libre disponible.

MySQL Connector/J inicialmente recupera el primer fetchSize grupo de filas, luego como rs.next() se mueve a través de ellos, eventualmente recuperará el siguiente grupo de filas. Eso es cierto incluso para setFetchSize(1) que, por cierto, es la manera de realmente obtener sólo una fila a la vez.

(Tenga en cuenta que setFetchSize(n) para n>0 requiere useCursorFetch=true en la URL de conexión. Aparentemente, eso no es necesario para setFetchSize(Integer.MIN_VALUE) .)