Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Czy MySQL Connector/J buforuje wiersze podczas przesyłania strumieniowego zestawu wyników?

Tak jest, przynajmniej czasami. Przetestowałem zachowanie MySQL Connector/J w wersji 5.1.37 za pomocą Wireshark. Do stołu...

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

... z danymi testowymi ...

 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)

... i kod ...

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

... bezpośrednio po s.executeQuery(sql) – czyli przed rs.next() jest nawet nazywany – MySQL Connector/J pobrał pierwsze ~140 wierszy z tabeli.

W rzeczywistości, gdy wysyłasz zapytanie tylko do tag kolumna

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

MySQL Connector/J natychmiast pobrał wszystkie 1000 wierszy, jak pokazano na liście ramek sieciowych Wireshark:

Ramka 19, która wysyłała zapytanie do serwera, wyglądała tak:

Serwer MySQL odpowiedział ramką 20, która rozpoczęła się od ...

... i natychmiast nastąpiła klatka 21, która zaczynała się od ...

... i tak dalej, aż serwer wysłał ramkę 32, która zakończyła się

Ponieważ jedyną różnicą była ilość informacji zwracanych dla każdego wiersza, możemy wywnioskować, że MySQL Connector/J decyduje o odpowiednim rozmiarze buforu na podstawie maksymalnej długości każdego zwróconego wiersza i ilości dostępnej wolnej pamięci.

MySQL Connector/J początkowo pobiera pierwszy fetchSize grupa wierszy, a następnie jako rs.next() przechodzi przez nie, ostatecznie pobierze następną grupę wierszy. To prawda nawet dla setFetchSize(1) co, nawiasem mówiąc, jest sposobem naprawdę otrzymuj tylko jeden wiersz na raz.

(Zauważ, że setFetchSize(n) dla n>0 wymaga useCursorFetch=true w adresie URL połączenia. To najwyraźniej nie jest wymagane dla setFetchSize(Integer.MIN_VALUE) .)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Neo4j - Upuść indeks za pomocą Cypher

  2. #1111 — Nieprawidłowe użycie funkcji grupy

  3. MySQL Query GROUP BY dzień / miesiąc / rok

  4. przesłać plik do bazy danych MySql za pomocą PHP

  5. Wiele formularzy i jedna strona przetwarzania