Every once in a while I want SQL*Plus to fetch one row at a time, so I set ARRAYSIZE to 1.
But:
SQL> set autotrace traceonly statistics SQL> set arraysize 1 SQL> select * from user1.cf1 where rownum <= 100; Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 102 consistent gets 0 physical reads 0 redo size 258194 bytes sent via SQL*Net to client 1091 bytes received via SQL*Net from client 51 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 100 rows processed
We only did 51 network round trips to fetch 100 rows. This is because SQL*Plus is using OCI and the default for prefetch (OCI_ATTR_PREFETCH_ROWS) is set to 1. So we end up with 2 rows per fetch call (note that with prefetch 1, the first round trip already returns 1 row).
Now, I really, really want to fetch just one row at a time. Starting with Oracle 12.1 you can create an OCI configuration file to specify various settings, one of them being prefetch. See documentation for more details.
vi ${TNS_ADMIN}/oraaccess.xml
<?xml version="1.0"?> <oraaccess xmlns="http://xmlns.oracle.com/oci/oraaccess" xmlns:oci="http://xmlns.oracle.com/oci/oraaccess" schemaLocation="http://xmlns.oracle.com/oci/oraaccess http://xmlns.oracle.com/oci/oraaccess.xsd"> <default_parameters> <prefetch> <rows>0</rows> </prefetch> </default_parameters> </oraaccess>
With this configuration in place we should see 100+ network round trips.
SQL> set autotrace traceonly statistics SQL> set arraysize 1 SQL> select * from user1.cf1 where rownum <= 100; Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 102 consistent gets 0 physical reads 0 redo size 267988 bytes sent via SQL*Net to client 1652 bytes received via SQL*Net from client 102 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 100 rows processed
Go play fetch 😉