Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Puffert MySQL Connector/J Zeilen, wenn ein ResultSet gestreamt wird?

Das tut es, zumindest manchmal. Ich habe das Verhalten von MySQL Connector/J Version 5.1.37 mit Wireshark getestet. Für die Tabelle ...

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

... mit Testdaten ...

 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)

... und der 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)) {

... unmittelbar nach s.executeQuery(sql) – also vor rs.next() wird sogar aufgerufen – MySQL Connector/J hatte die ersten ~140 Zeilen aus der Tabelle abgerufen.

In der Tat, wenn nur das tag abgefragt wird Spalte

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

MySQL Connector/J hat sofort alle 1000 Zeilen abgerufen, wie die Wireshark-Liste der Netzwerk-Frames zeigt:

Frame 19, der die Anfrage an den Server schickte, sah so aus:

Der MySQL-Server antwortete mit Frame 20, der mit ...

begann

... und wurde unmittelbar gefolgt von Frame 21, der mit ...

begann

... und so weiter, bis der Server Frame 32 gesendet hatte, der mit

endete

Da der einzige Unterschied in der Menge der für jede Zeile zurückgegebenen Informationen bestand, können wir schlussfolgern, dass MySQL Connector/J basierend auf der maximalen Länge jeder zurückgegebenen Zeile und der Menge an verfügbarem freiem Speicher über eine geeignete Puffergröße entscheidet.

MySQL Connector/J ruft zunächst die erste fetchSize ab Gruppe von Zeilen, dann als rs.next() sich durch sie bewegt, wird schließlich die nächste Gruppe von Zeilen abgerufen. Das gilt sogar für setFetchSize(1) das ist übrigens der Weg zu wirklich erhalten Sie jeweils nur eine Zeile.

(Beachten Sie, dass setFetchSize(n) für n>0 erfordert useCursorFetch=true in der Verbindungs-URL. Für setFetchSize(Integer.MIN_VALUE) ist das offenbar nicht erforderlich .)