PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

SQL LIMIT vs. Pernyataan JDBC setMaxRows. Mana yang lebih baik?

LIMIT tingkat SQL

Untuk membatasi ukuran kumpulan hasil kueri SQL, Anda dapat menggunakan sintaks SQL:008:

SELECT title
FROM post
ORDER BY created_on DESC
OFFSET 50 ROWS
FETCH NEXT 50 ROWS ONLY

yang bekerja pada Oracle 12, SQL Server 2012, atau PostgreSQL 8.4 atau versi yang lebih baru.

Untuk MySQL, Anda dapat menggunakan klausa LIMIT dan OFFSET:

SELECT title
FROM post
ORDER BY created_on DESC
LIMIT 50
OFFSET 50

Keuntungan menggunakan pagination tingkat SQL adalah bahwa rencana eksekusi database dapat menggunakan informasi ini.

Jadi, jika kita memiliki indeks pada created_on kolom:

CREATE INDEX idx_post_created_on ON post (created_on DESC)

Dan kami menjalankan kueri berikut yang menggunakan LIMIT klausa:

EXPLAIN ANALYZE
SELECT title
FROM post
ORDER BY created_on DESC
LIMIT 50

Kita dapat melihat bahwa mesin database menggunakan indeks karena pengoptimal mengetahui bahwa hanya 50 record yang akan diambil:

Execution plan:
Limit  (cost=0.28..25.35 rows=50 width=564)
       (actual time=0.038..0.051 rows=50 loops=1)
  ->  Index Scan using idx_post_created_on on post p  
      (cost=0.28..260.04 rows=518 width=564) 
      (actual time=0.037..0.049 rows=50 loops=1)
Planning time: 1.511 ms
Execution time: 0.148 ms

JDBC Statement maxRows

Menurut setMaxRows Javadoc :

Itu tidak terlalu meyakinkan!

Jadi, jika kita mengeksekusi query berikut di PostgreSQL:

try (PreparedStatement statement = connection
    .prepareStatement("""
        SELECT title
        FROM post
        ORDER BY created_on DESC
    """)
) {
    statement.setMaxRows(50);
    ResultSet resultSet = statement.executeQuery();
    int count = 0;
    while (resultSet.next()) {
        String title = resultSet.getString(1);
        count++;
    }
}

Kami mendapatkan rencana eksekusi berikut di log PostgreSQL:

Execution plan:
  Sort  (cost=65.53..66.83 rows=518 width=564) 
        (actual time=4.339..5.473 rows=5000 loops=1)
  Sort Key: created_on DESC
  Sort Method: quicksort  Memory: 896kB
  ->  Seq Scan on post p  (cost=0.00..42.18 rows=518 width=564) 
                          (actual time=0.041..1.833 rows=5000 loops=1)
Planning time: 1.840 ms
Execution time: 6.611 ms 

Karena pengoptimal basis data tidak tahu bahwa kita hanya perlu mengambil 50 catatan, ia mengasumsikan bahwa semua 5000 baris perlu dipindai. Jika kueri perlu mengambil sejumlah besar catatan, biaya pemindaian tabel lengkap sebenarnya lebih rendah daripada jika indeks digunakan, maka rencana eksekusi tidak akan menggunakan indeks sama sekali.

Kesimpulan

Meskipun terlihat seperti setMaxRows adalah solusi portabel untuk membatasi ukuran ResultSet , pagination tingkat SQL jauh lebih efisien jika pengoptimal server database tidak menggunakan maxRows JDBC properti.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Merujuk dan Menyimpan Beberapa User_ID ke satu formulir dan tampilan kata Id di indeks / Tampilkan Halaman Aplikasi Rails 4

  2. Mengapa iterasi melalui Django QuerySet besar menghabiskan banyak memori?

  3. Bisakah seseorang menjelaskan apa itu klien postgresql dan bagaimana interaksinya dengan paket inti postgresql?

  4. Bisakah referensi kunci asing berisi nilai NULL di PostgreSQL?

  5. Perbedaan antara dua tanggal di postgresql