Rumah > Artikel > pangkalan data > Menstrim kaedah pertanyaan dan pertanyaan kursor dalam MySQL (perkongsian ringkasan)
Artikel ini membawakan anda pengetahuan yang berkaitan tentang mysql Ia terutamanya memperkenalkan pertanyaan penstriman dan kaedah pertanyaan kursor dalam MySQL Ia mempunyai nilai rujukan yang baik dan saya harap ia akan membantu semua orang.
Pembelajaran yang disyorkan: tutorial video mysql
Dengan mengandaikan satu jadual mempunyai volum data sebanyak 5 juta, tiada siapa yang akan memuatkannya ke dalam memori sekali gus dan paging biasanya digunakan.
Di sini, demo ujian hanyalah untuk memantau JVM, jadi paging tidak digunakan dan data dimuatkan ke dalam memori pada satu masa
@Test public void generalQuery() throws Exception { // 1核2G:查询一百条记录:47ms // 1核2G:查询一千条记录:2050 ms // 1核2G:查询一万条记录:26589 ms // 1核2G:查询五万条记录:135966 ms String sql = "select * from wh_b_inventory limit 10000"; ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(sql); int count = 0; while (rs.next()) { count++; } System.out.println(count); }Pemantauan JVM
Kami akan mengurangkan saiz memori - melebihi had overhed GC
1 Kerap mencetuskan GCAda risiko OOM
2.2 Pertanyaan penstriman
Satu perkara yang perlu diambil perhatian tentang pertanyaan penstriman: semua baris dalam set hasil mesti dibaca (atau ditutup) sebelum sebarang pertanyaan lain boleh dikeluarkan pada sambungan, jika tidak pengecualian akan dilemparkan dan pertanyaan akan memonopoli sambungan.
Daripada keputusan ujian, pertanyaan penstriman tidak meningkatkan kelajuan pertanyaan
Pemantauan JVMKami akan mengurangkan memori timbunan -Xms70m -Xmx70m
@Test public void streamQuery() throws Exception { // 1核2G:查询一百条记录:138ms // 1核2G:查询一千条记录:2304 ms // 1核2G:查询一万条记录:26536 ms // 1核2G:查询五万条记录:135931 ms String sql = "select * from wh_b_inventory limit 50000"; statement = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); statement.setFetchSize(Integer.MIN_VALUE); ResultSet rs = statement.executeQuery(sql); int count = 0; while (rs.next()) { count++; } System.out.println(count); }Kami mendapati bahawa walaupun ingatan timbunan hanya 70m, OOM masih tidak berlaku
2.3 Pertanyaan kursor
Nota :
1. Parameter perlu disambungkan ke dalam maklumat sambungan pangkalan data useCursorFetch=true
2 , seperti 1000 pada satu masaBerdasarkan keputusan ujian, pertanyaan kursor telah memendekkan kelajuan pertanyaan pada tahap tertentu
Pemantauan JVM
Kami akan timbunan Kurangkan saiz memori -
@Test public void cursorQuery() throws Exception { Class.forName("com.mysql.jdbc.Driver"); // 注意这里需要拼接参数,否则就是普通查询 conn = DriverManager.getConnection("jdbc:mysql://101.34.50.82:3306/mysql-demo?useCursorFetch=true", "root", "123456"); start = System.currentTimeMillis(); // 1核2G:查询一百条记录:52 ms // 1核2G:查询一千条记录:1095 ms // 1核2G:查询一万条记录:17432 ms // 1核2G:查询五万条记录:90244 ms String sql = "select * from wh_b_inventory limit 50000"; ((JDBC4Connection) conn).setUseCursorFetch(true); statement = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); statement.setFetchSize(1000); ResultSet rs = statement.executeQuery(sql); int count = 0; while (rs.next()) { count++; } System.out.println(count); }
3. RowDataLogik ResultSet.next() adalah untuk melaksanakan kelas ResultSetImpl dan dapatkannya daripada RowData setiap kali Data untuk baris seterusnya. RowData ialah antara muka dan rajah perhubungan pelaksanaan adalah seperti berikut
3.1 RowDataStatic
3.2 RowDataDynamic
Apabila pemprosesan penstriman digunakan, ResultSet menggunakan objek RowDataDynamic, dan Setiap panggilan ke objek next() ini akan memulakan IO untuk membaca satu baris data
3.3 RowDataCursorPanggilan ke RowDataCursor adalah pemprosesan kelompok, dan kemudian dicache secara dalaman. Prosesnya adalah seperti berikut:Jika semua bacaan selesai, cetuskan permintaan baharu kepada Pelayan MySQL untuk membaca hasil kuantiti fetchSize
4. Prinsip komunikasi JDBC
Interaksi antara JDBC dan pelayan MySQL diselesaikan melalui Socket Sesuai dengan pengaturcaraan rangkaian, MySQL boleh dianggap sebagai SocketServer, jadi pautan permintaan yang lengkap :Pelanggan JDBC-> Soket Pelanggan -> >4.1 generalQuery Pertanyaan umum
Jika jumlah data pertanyaan terlalu besar, ia akan terus mengalami GC, dan kemudian akan berlaku limpahan memori
4.2 pertanyaan penstriman streamQuery
4.3 cursorQuery Cursor Query
Jadi apabila anda mendayakan useCursorFetch untuk membaca jadual besar, anda akan melihat beberapa fenomena pada MySQL:
1 IOPS melonjak 2Panggilan serentak juga OK untuk penggunaan memori, tidak wujud Peningkatan bertindan
Laporan prestasi memori pertanyaan kursor adalah seperti berikut 6. Ringkasan1. Kedua-dua pertanyaan kursor dan pertanyaan penstriman boleh mengelakkan OOM dalam satu urutan; pertanyaan. Masa;
Pembelajaran yang disyorkan:
tutorial video mysqlAtas ialah kandungan terperinci Menstrim kaedah pertanyaan dan pertanyaan kursor dalam MySQL (perkongsian ringkasan). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!