Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL Connector/J tamponne-t-il les lignes lors de la diffusion d'un ResultSet ?

C'est le cas, du moins parfois. J'ai testé le comportement de MySQL Connector/J version 5.1.37 en utilisant Wireshark. Pour le tableau...

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

... avec des données de test ...

 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)

... et le code ...

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)) {

... immédiatement après le s.executeQuery(sql) – c'est-à-dire avant rs.next() est même appelé - MySQL Connector/J avait récupéré les ~140 premières lignes de la table.

En fait, lorsque vous interrogez uniquement le tag colonne

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

MySQL Connector/J a immédiatement récupéré les 1000 lignes comme indiqué par la liste Wireshark des trames réseau :

L'image 19, qui envoyait la requête au serveur, ressemblait à ceci :

Le serveur MySQL a répondu avec la trame 20, qui commençait par ...

... et était immédiatement suivi par l'image 21, qui commençait par ...

... et ainsi de suite jusqu'à ce que le serveur ait envoyé la trame 32, qui se termine par

Étant donné que la seule différence était la quantité d'informations renvoyées pour chaque ligne, nous pouvons conclure que MySQL Connector/J décide d'une taille de tampon appropriée en fonction de la longueur maximale de chaque ligne renvoyée et de la quantité de mémoire libre disponible.

MySQL Connector/J récupère initialement le premier fetchSize groupe de lignes, puis comme rs.next() les parcourt, il finira par récupérer le groupe de lignes suivant. Cela est vrai même pour setFetchSize(1) qui, soit dit en passant, est le moyen de vraiment obtenir une seule ligne à la fois.

(Notez que setFetchSize(n) pour n>0 nécessite useCursorFetch=true dans l'URL de connexion. Ce n'est apparemment pas nécessaire pour setFetchSize(Integer.MIN_VALUE) .)