Fahami kefungsian kaedah Statement.setFetchSize(nSize) dalam pemacu JDBC SQL Server
P粉463811100
2023-08-27 17:05:57
<p>Saya mempunyai jadual yang sangat besar dengan berjuta-juta rekod setiap hari, dan pada penghujung setiap hari saya menarik semua rekod dari hari sebelumnya. Beginilah cara saya melakukannya: </p>
<pre class="brush:php;toolbar:false;">String SQL = "pilih col1, col2, coln from mytable where timecol = semalam";
Statement.executeQuery(SQL);</pre>
<p>Masalahnya ialah program ini memerlukan kira-kira 2GB memori kerana ia meletakkan semua keputusan dalam ingatan dan kemudian memprosesnya. </p>
<p>Saya cuba menetapkan <code>Statement.setFetchSize(10)</code> tetapi ia mendapat memori yang sama daripada OS, tiada perbezaan. Saya menggunakan <em>Microsoft SQL Server 2005 JDBC Driver</em> </p>
<p>Adakah terdapat sebarang cara untuk membaca keputusan dalam ketulan kecil seperti pemacu pangkalan data Oracle, menunjukkan hanya beberapa baris apabila pertanyaan dilaksanakan dan lebih banyak hasil semasa anda menatal ke bawah? </p>
Dalam JDBC, kaedah
setFetchSize(int)
sangat penting untuk prestasi dan pengurusan memori dalam JVM, kerana ia mengawal bilangan panggilan rangkaian daripada JVM ke pangkalan data dan jumlah data yang sepadan. RAM digunakan untuk pemprosesan set hasil.Pada asasnya, jika setFetchSize(10) dipanggil dan pemandu mengabaikannya, hanya terdapat dua pilihan yang mungkin:
RESULT-SET ialah bilangan baris yang disusun pada pangkalan data sebagai tindak balas kepada pertanyaan. ROW-SET ialah blok baris yang diekstrak daripada RESULT-SET pada setiap panggilan daripada JVM ke DB. Bilangan panggilan ini dan RAM yang diperlukan untuk pemprosesan, bergantung pada tetapan saiz pengambilan.
Jadi jika RESULT-SET mempunyai 100 baris dan saiz pengambilan ialah 10, Pada bila-bila masa, terdapat 10 panggilan rangkaian untuk mendapatkan semula semua data, menggunakan kira-kira 10*{row-content-size} RAM.
Saiz pengambilan lalai ialah 10, yang agak kecil. Dalam kes yang disiarkan, pemandu nampaknya mengabaikan tetapan saiz pengambilan, mendapatkan semula semua data dalam satu panggilan (memerlukan banyak RAM, panggilan rangkaian minimum yang optimum).
Apa yang berlaku di bawah
ResultSet.next()
ialah ia sebenarnya tidak mendapat satu baris pada satu masa daripada RESULT-SET. Ia mendapat data itu daripada ROW-SET (tempatan) dan mendapat ROW-SET seterusnya (tidak kelihatan) daripada pelayan apabila data pada klien tempatan telah habis.Semua ini bergantung pada pemacu, kerana persediaan hanyalah "petunjuk", tetapi dalam praktiknya saya mendapati bahawa ini adalah bilangan pemacu dan pangkalan data yang berfungsi (terbukti dalam banyak versi Oracle, DB2 dan MySQL). p>