Apa cara terbaik (kinerja bijaksana) untuk hasil paginasi dalam SQL Server 2000, 2005, 2008, 2012 jika Anda juga ingin mendapatkan jumlah total hasil (sebelum paginasi)?
sql
sql-server
performance
pagination
Panagiotis Korros
sumber
sumber
Jawaban:
Mendapatkan jumlah total hasil dan paginasi adalah dua operasi yang berbeda. Demi contoh ini, mari kita asumsikan bahwa kueri yang Anda hadapi adalah
Dalam hal ini, Anda akan menentukan jumlah total hasil menggunakan:
... yang mungkin tampak tidak efisien, tetapi sebenarnya cukup performan, dengan asumsi semua indeks dll sudah diatur dengan benar.
Selanjutnya, untuk mendapatkan hasil yang sebenarnya dalam mode halaman, permintaan berikut akan paling efisien:
Ini akan mengembalikan baris 1-19 dari permintaan asli. Yang paling keren di sini, terutama untuk aplikasi web, adalah Anda tidak perlu mempertahankan status apa pun, kecuali nomor baris yang harus dikembalikan.
sumber
Akhirnya, Microsoft SQL Server 2012 dirilis, saya sangat suka kesederhanaannya untuk pagination, Anda tidak harus menggunakan pertanyaan kompleks seperti dijawab di sini.
Untuk mendapatkan 10 baris berikutnya jalankan saja query ini:
https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql#using-offset-and-fetch-to-limit-the-rows- dikembalikan
Poin-poin penting untuk dipertimbangkan ketika menggunakannya:
ORDER BY
wajib menggunakanOFFSET ... FETCH
klausa.OFFSET
klausa wajib denganFETCH
. Anda tidak dapat menggunakanORDER BY ... FETCH
.TOP
tidak dapat digabungkan denganOFFSET
danFETCH
dalam ekspresi kueri yang sama.sumber
LISTAGG()
/GROUP_CONCAT()
.FOR XML
: stackoverflow.com/a/273330/429949FOR XML PATH ('')
. Pertama, ia menggantikan karakter kontrol XML dengan kode entitas XML. Harap Anda tidak memiliki<
,>
atau&
dalam data Anda! Kedua,FOR XML PATH ('')
digunakan dengan cara ini sebenarnya sintaksis tidak berdokumen. Anda seharusnya menentukan kolom bernama atau nama elemen pengganti. Tidak melakukan keduanya tidak ada dalam dokumen, berarti perilaku tersebut tidak dapat diandalkan. Ketiga, semakin kita menerimaFOR XML PATH ('')
sintaks yang rusak , semakin kecil kemungkinannya bahwa MS benar-benar menyediakan fungsi nyataLISTAGG() [ OVER() ]
seperti yang mereka butuhkan.Luar biasa, tidak ada jawaban lain yang menyebutkan cara tercepat untuk melakukan pagination di semua versi SQL Server. Offset bisa sangat lambat untuk nomor halaman besar seperti yang ditentukan di sini . Ada cara yang sama sekali berbeda, jauh lebih cepat untuk melakukan pagination dalam SQL. Ini sering disebut "mencari metode" atau "pagination keyset" seperti yang dijelaskan dalam posting blog ini di sini .
"Mencari predikat"
Nilai
@previousScore
dan@previousPlayerId
adalah nilai masing-masing dari catatan terakhir dari halaman sebelumnya. Ini memungkinkan Anda untuk mengambil halaman "selanjutnya". JikaORDER BY
arahnyaASC
, gunakan>
saja.Dengan metode di atas, Anda tidak dapat langsung melompat ke halaman 4 tanpa terlebih dahulu mengambil 40 catatan sebelumnya. Namun seringkali, Anda tidak ingin melompat sejauh itu. Alih-alih, Anda mendapatkan kueri yang jauh lebih cepat yang mungkin dapat mengambil data dalam waktu konstan, tergantung pada pengindeksan Anda. Plus, halaman Anda tetap "stabil", tidak masalah jika data yang mendasarinya berubah (misalnya di halaman 1, saat Anda di halaman 4).
Ini adalah cara terbaik untuk mengimplementasikan pagination ketika malas memuat lebih banyak data dalam aplikasi web, misalnya.
Catatan, "metode pencarian" juga disebut pagination keyset .
Total catatan sebelum pagination
Fungsi
COUNT(*) OVER()
jendela akan membantu Anda menghitung jumlah total catatan "sebelum pagination". Jika Anda menggunakan SQL Server 2000, Anda harus menggunakan dua kueri untukCOUNT(*)
.sumber
OFFSET .. FETCH
, atau denganROW_NUMBER()
trik sebelumnya .RowNumber
memberi saya 10 item yang konsisten per halaman. [3] itu tidak berfungsi dengan kisi-kisi yang ada yang menganggappagenumber
danpagesize
.Dari SQL Server 2012, kita dapat menggunakan
OFFSET
danFETCH NEXT
Klausul untuk mencapai pagination.Coba ini, untuk SQL Server:
TechNet: Paging Query dengan SQL Server
sumber
MSDN: ROW_NUMBER (Transact-SQL)
sumber
Ada gambaran bagus tentang berbagai teknik paging di http://www.codeproject.com/KB/aspnet/PagingLarge.aspx
Saya telah menggunakan metode ROWCOUNT cukup sering sebagian besar dengan SQL Server 2000 (akan bekerja dengan 2005 & 2008 juga, hanya mengukur kinerja dibandingkan dengan ROW_NUMBER), sangat cepat, tetapi Anda perlu memastikan bahwa kolom yang disortir memiliki (kebanyakan) ) nilai unik.
sumber
Untuk SQL Server 2000 Anda dapat mensimulasikan ROW_NUMBER () menggunakan variabel tabel dengan kolom IDENTITY:
Pendekatan ini dapat diperluas ke tabel dengan kunci multi-kolom, dan itu tidak menimbulkan kinerja overhead menggunakan OR (yang melompati penggunaan indeks). Kelemahannya adalah jumlah ruang sementara yang digunakan jika kumpulan data sangat besar dan satu berada di dekat halaman terakhir. Saya tidak menguji kinerja kursor dalam kasus itu, tetapi mungkin lebih baik.
Perhatikan bahwa pendekatan ini dapat dioptimalkan untuk halaman data pertama. Juga, ROWCOUNT digunakan karena TOP tidak menerima variabel dalam SQL Server 2000.
sumber
Cara terbaik untuk paging di sql server 2012 adalah dengan menggunakan offset dan mengambil berikutnya dalam prosedur tersimpan. Kata Kunci OFFSET - Jika kita menggunakan offset dengan urutan dengan klausa maka kueri akan melewati jumlah catatan yang kita tentukan di OFFSET dan Baris.
FETCH NEXT Keywords - Ketika kita menggunakan Fetch Next dengan pesanan dengan klausa hanya akan mengembalikan jumlah baris yang ingin Anda tampilkan dalam paging, tanpa Offset maka SQL akan menghasilkan kesalahan. di sini adalah contoh yang diberikan di bawah ini.
Anda dapat menjalankannya sebagai berikut.
sumber
Ini adalah solusi saya untuk mem-paging hasil query di sisi SQL server. pendekatan ini berbeda antara SQL Server 2008 dan 2012. Juga, saya telah menambahkan konsep penyaringan dan pesanan dengan satu kolom. Ini sangat efisien ketika Anda melakukan paging dan memfilter serta memesan di Gridview Anda.
Sebelum pengujian, Anda harus membuat satu tabel contoh dan memasukkan beberapa baris dalam tabel ini: (Di dunia nyata Anda harus mengubah Di mana klausa mempertimbangkan bidang tabel Anda dan mungkin Anda memiliki beberapa gabungan dan subquery di bagian utama pilih)
Dalam semua sampel ini, saya ingin meminta 200 baris per halaman dan saya mengambil baris untuk nomor halaman 1200.
Di SQL server 2008, Anda dapat menggunakan konsep CTE. Karena itu, saya telah menulis dua jenis kueri untuk SQL server 2008+
- SQL Server 2008+
Dan solusi kedua dengan CTE di SQL server 2008+
- SQL Server 2012+
sumber
Coba pendekatan ini:
sumber
Gunakan case bijaksana berikut ini tampaknya mudah digunakan dan cepat. Cukup atur nomor halaman.
juga tanpa CTE
sumber
Yah saya telah menggunakan contoh permintaan berikut dalam database SQL 2000 saya, itu berfungsi dengan baik untuk SQL 2005 juga. Kekuatan yang diberikannya kepada Anda adalah urutan dinamis dengan menggunakan beberapa kolom. Saya katakan ... ini sangat ampuh :)
Bagian terbaiknya adalah sp_executesql cache panggilan kemudian, asalkan Anda melewati parameter yang sama yaitu menghasilkan teks sql yang sama.
sumber
akan memulai ulang idx ketika datang ke init_id yang berbeda
sumber
Untuk
ROW_NUMBER
tekniknya, jika Anda tidak memiliki kolom penyortiran untuk digunakan, Anda dapat menggunakanCURRENT_TIMESTAMP
sebagai berikut:Ini telah bekerja dengan baik bagi saya untuk pencarian di atas ukuran meja bahkan hingga 700.000.
Ini mengambil catatan 11 hingga 30.
sumber
sumber
Bit ini memberi Anda kemampuan untuk melakukan paginasi menggunakan SQL Server, dan versi MySQL yang lebih baru dan membawa jumlah total baris di setiap baris. Gunakan kunci pimary Anda untuk menghitung jumlah baris unik.
sumber
Ini adalah duplikat dari pertanyaan SO lama 2012: cara efisien untuk menerapkan paging
Di sini topik dibahas secara lebih rinci, dan dengan pendekatan alternatif.
sumber
Mulai 2012 dan selanjutnya kita bisa menggunakan
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY
sumber
Anda tidak menentukan bahasa atau driver yang Anda gunakan. Karena itu saya jelaskan secara abstrak.
sumber