Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Kinerja SQL:WHERE vs WHERE(ROW_NUMBER)

Seperti yang sudah ditunjukkan oleh orang lain, kueri mengembalikan hasil yang berbeda dan membandingkan apel dengan jeruk.

Namun pertanyaan mendasarnya tetap:mana yang lebih cepat:paging yang digerakkan oleh keyset atau paging yang digerakkan oleh nomor baris?

Paging Keyset

Paging berbasis keyset bergantung pada mengingat tombol atas dan bawah dari halaman yang terakhir ditampilkan, dan meminta rangkaian baris berikutnya atau sebelumnya, berdasarkan keyset atas/terakhir:

Halaman berikutnya:

select top (<pagesize>) ...
from <table>
where key > @last_key_on_current_page
order by key;

Halaman sebelumnya:

select top (<pagesize>)
from <table>
where key < @first_key_on_current_page
order by key desc;

Pendekatan ini memiliki dua keunggulan utama dibandingkan pendekatan ROW_NUMBER, atau dibandingkan dengan pendekatan LIMIT yang setara dengan MySQL:

  • adalah benar :tidak seperti pendekatan berbasis nomor baris, ini menangani entri baru dan entri yang dihapus dengan benar. Baris terakhir Halaman 4 tidak muncul sebagai baris pertama Halaman 5 hanya karena baris 23 pada Halaman 2 telah dihapus sementara. Baris juga tidak menghilang secara misterius di antara halaman. Anomali ini umum terjadi pada pendekatan berbasis row_number, tetapi solusi berbasis kumpulan kunci melakukan pekerjaan yang jauh lebih baik untuk menghindarinya.
  • cepat :semua operasi dapat diselesaikan dengan pemosisian baris cepat diikuti dengan pemindaian jarak ke arah yang diinginkan

Namun, pendekatan ini sulit untuk diimplementasikan, sulit dipahami oleh programmer rata-rata dan tidak didukung oleh alat.

Didorong Nomor Baris

Ini adalah pendekatan umum yang diperkenalkan dengan kueri Linq:

select ...
from (
  select ..., row_number() over (...) as rn
  from table)
where rn between @firstRow and @lastRow;

(atau kueri serupa menggunakan TOP)Pendekatan ini mudah untuk diimplementasikan dan didukung oleh alat (khususnya oleh operator Linq .Limit dan .Take). Tapi pendekatan ini dijamin untuk memindai indeks untuk menghitung baris. Pendekatan ini biasanya bekerja dengan sangat cepat untuk halaman 1 dan perlahan-lahan melambat saat yang satu menuju ke nomor halaman yang lebih tinggi dan lebih tinggi lagi.

Sebagai bonus, dengan solusi ini sangat mudah untuk mengubah urutan pengurutan (cukup ubah klausa OVER).

Secara keseluruhan, mengingat kemudahan solusi berbasis ROW_NUMBER(), dukungan yang mereka miliki dari Linq, kesederhanaan untuk menggunakan perintah arbitrer untuk set data moderat solusi berbasis ROW_NUMBER sudah memadai. Untuk kumpulan data yang besar dan sangat besar, ROW_NUMBER() dapat menyebabkan masalah kinerja yang serius.

Satu hal lagi yang perlu dipertimbangkan adalah bahwa seringkali ada pola akses yang pasti. Seringkali beberapa halaman pertama panas dan halaman setelah 10 pada dasarnya tidak pernah dilihat (misalnya posting terbaru). Dalam hal ini, penalti yang terjadi dengan ROW_NUMBER() untuk mengunjungi halaman bawah (halaman yang menampilkan banyak baris harus dihitung untuk mendapatkan baris hasil awal) dapat diabaikan.

Dan akhirnya, pagination keyset sangat bagus untuk navigasi kamus, yang tidak dapat diakomodasi dengan mudah oleh ROW_NUMBER(). Navigasi kamus adalah tempat alih-alih menggunakan nomor halaman, pengguna dapat menavigasi ke jangkar tertentu, seperti huruf alfabet. Contoh umum adalah kontak Rolodex seperti sidebar, Anda mengklik M dan Anda menavigasi ke nama pelanggan pertama yang dimulai dengan M.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mencatat SEMUA Pertanyaan di Database SQL Server 2008 Express?

  2. Konfigurasikan Lingkungan StartUp di SQL Server Management Studio (SSMS) - Tutorial SQL Server / TSQL Bagian 7

  3. Bagaimana saya bisa melakukan pernyataan UPDATE dengan JOIN di SQL Server?

  4. Mengapa menggunakan karakter Garis Bawah dalam filter LIKE memberi saya semua hasil?

  5. Berapa ukuran yang Anda gunakan untuk varchar(MAX) dalam deklarasi parameter Anda?