Така е, поне понякога. Тествах поведението на MySQL Connector/J версия 5.1.37 с помощта на Wireshark. За масата...
CREATE TABLE lorem (
id INT AUTO_INCREMENT PRIMARY KEY,
tag VARCHAR(7),
text1 VARCHAR(255),
text2 VARCHAR(255)
)
... с тестови данни ...
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)
... и кодът ...
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)) {
... непосредствено след s.executeQuery(sql)
– т.е. преди rs.next()
дори се нарича – MySQL Connector/J извлече първите ~140 реда от таблицата.
Всъщност, когато отправяте заявка само към tag
колона
String sql = "SELECT tag FROM lorem ORDER BY id";
MySQL Connector/J незабавно извлече всичките 1000 реда, както е показано от списъка на Wireshark с мрежови рамки:
Рамка 19, която изпрати заявката до сървъра, изглеждаше така:
MySQL сървърът отговори с кадър 20, който започва с ...
... и веднага беше последван от кадър 21, който започваше с ...
... и така нататък, докато сървърът не изпрати кадър 32, който завърши с
Тъй като единствената разлика е количеството информация, която се връща за всеки ред, можем да заключим, че MySQL Connector/J решава подходящ размер на буфера въз основа на максималната дължина на всеки върнат ред и количеството налична свободна памет.
MySQL Connector/J първоначално извлича първия fetchSize
група от редове, след това като rs.next()
се движи през тях, в крайна сметка ще извлече следващата група редове. Това е вярно дори за setFetchSize(1)
което, между другото, е пътят за наистина получавате само един ред наведнъж.
(Обърнете внимание, че setFetchSize(n)
за n>0 изисква useCursorFetch=true
в URL адреса на връзката. Това очевидно не се изисква за setFetchSize(Integer.MIN_VALUE)
.)