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