Meskipun posting ini tidak akan menjadi jawaban yang lengkap karena kekurangan informasi, pos ini seharusnya dapat mengarahkan Anda ke arah yang tepat atau mendapatkan wawasan yang nantinya dapat Anda bagikan dengan komunitas.
Sayangnya, definisi ini menghasilkan penurunan kinerja sehubungan dengan situasi sebelumnya dengan tabel berbasis disk. Urutan besarnya lebih atau kurang 10% lebih tinggi (yang dalam beberapa kasus mencapai 100%, jadi dua kali lipat).
Yang paling utama, saya mengharapkan untuk mendapatkan keuntungan super dalam skenario konkurensi tinggi, mengingat arsitektur bebas kunci yang diiklankan oleh Microsoft. Sebagai gantinya, kinerja terburuk adalah persis ketika ada beberapa pengguna bersamaan menjalankan beberapa pertanyaan di atas meja.
Ini menyusahkan karena seharusnya tidak demikian. Beban kerja tertentu tidak untuk dalam tabel memori (SQL 2014) dan beberapa beban kerja sesuai untuk itu. Dalam sebagian besar situasi mungkin ada sedikit peningkatan kinerja hanya dengan bermigrasi dan memilih indeks yang tepat.
Awalnya saya berpikir sangat sempit tentang pertanyaan Anda mengenai hal ini:
Pertanyaan:
- berapa BUCKET_COUNT yang benar untuk ditetapkan?
- indeks apa yang harus saya gunakan?
- mengapa kinerjanya lebih buruk daripada dengan tabel berbasis disk?
Awalnya saya percaya akan ada masalah dengan aktual dalam tabel memori dan indeks tidak optimal. Meskipun ada beberapa masalah dengan memori yang dioptimalkan definisi indeks hash saya percaya masalah sebenarnya adalah dengan pertanyaan yang digunakan.
-- INSERT (can vary from 10s to 10,000s of records):
INSERT INTO MyTable
SELECT @fixedValue, id2, col1, col2 FROM AnotherTable
Sisipan ini harus sangat cepat jika hanya melibatkan tabel memori. Namun, ini juga melibatkan tabel berbasis disk dan tunduk pada semua penguncian dan pemblokiran yang terkait dengannya. Dengan demikian, pemborosan waktu nyata di sini adalah pada tabel berbasis disk.
Ketika saya melakukan tes cepat terhadap 100.000 baris memasukkan dari tabel berbasis disk setelah memuat data ke dalam memori - itu adalah waktu respon sub-detik. Namun, sebagian besar data Anda hanya disimpan untuk waktu yang sangat singkat, kurang dari 20 detik. Ini tidak memberikan banyak waktu untuk benar-benar hidup dalam cache. Selain itu saya tidak yakin seberapa besar AnotherTable
sebenarnya dan tidak tahu apakah nilai sedang dibaca dari disk atau tidak. Kami harus mengandalkan Anda untuk jawaban ini.
Dengan kueri Select:
SELECT id2, col1
FROM MyTable INNER JOIN OtherTbl ON MyTable.id2 = OtherTbl.pk
WHERE id1 = @value
ORDER BY col1
Sekali lagi, kita berada di tangan kinerja tabel berbasis disk + interop. Selain itu, jenis tidak murah pada indeks HASH dan indeks nonclustered harus digunakan. Ini disebut dalam panduan Indeks yang saya tautkan dalam komentar.
Untuk memberikan beberapa fakta berdasarkan penelitian aktual, saya memuat SearchItems
tabel memori dengan 10 juta baris dan AnotherTable
dengan 100.000 karena saya tidak tahu ukuran aktual atau statistiknya. Saya kemudian menggunakan kueri pemilihan di atas untuk mengeksekusi. Selain itu saya membuat sesi acara diperpanjang pada wait_completed dan memasukkannya ke dalam buffer cincin. Itu dibersihkan setelah setiap kali dijalankan. Saya juga berlari DBCC DROPCLEANBUFFERS
untuk mensimulasikan lingkungan di mana semua data mungkin bukan memori.
Hasilnya bukanlah sesuatu yang spektakuler ketika melihatnya dalam ruang hampa. Karena laptop yang saya uji ini menggunakan SSD kelas yang lebih tinggi, saya secara artifisial menurunkan kinerja berbasis disk untuk VM yang saya gunakan.
Hasilnya masuk tanpa info tunggu setelah 5 kali menjalankan kueri hanya pada tabel berbasis di-memori (menghapus gabungan dan tidak ada sub-kueri). Ini seperti yang diharapkan.
Namun, saat menggunakan kueri asli, saya sudah menunggu. Dalam hal ini adalah PAGEIOLATCH_SH yang masuk akal karena data sedang dibaca dari disk. Karena saya adalah satu - satunya pengguna dalam sistem ini dan tidak menghabiskan waktu untuk membuat lingkungan pengujian besar-besaran untuk memasukkan, memperbarui, menghapus terhadap tabel yang digabungkan, saya tidak mengharapkan penguncian atau pemblokiran mulai berlaku.
Dalam hal ini, sekali lagi, sebagian besar waktu dihabiskan di atas meja berbasis disk.
Akhirnya kueri penghapusan. Menemukan baris berdasarkan hanya ID1 tidak sangat efisien dengan indeks has. Meskipun benar bahwa predikat kesetaraan adalah indeks hash yang tepat untuknya, bucket yang digunakan untuk memasukkan data didasarkan pada seluruh kolom hash. Jadi id1, id2 di mana id1 = 1, id2 = 2, dan id1 = 1, id2 = 3 akan hash ke dalam ember yang berbeda seperti hash akan melintasi (1,2) dan (1,3). Ini tidak akan menjadi pemindaian rentang B-Tree sederhana karena indeks hash tidak terstruktur dengan cara yang sama. Saya kemudian berharap ini bukan indeks yang ideal untuk operasi ini, namun saya tidak akan mengharapkannya untuk mengambil pesanan yang lebih besar seperti yang dialami. Saya akan tertarik melihat wait_info tentang ini.
Yang paling utama, saya mengharapkan untuk mendapatkan keuntungan super dalam skenario konkurensi tinggi, mengingat arsitektur bebas kunci yang diiklankan oleh Microsoft. Sebagai gantinya, kinerja terburuk adalah persis ketika ada beberapa pengguna bersamaan menjalankan beberapa pertanyaan di atas meja.
Meskipun benar bahwa kunci digunakan untuk konsistensi logis, operasi masih harus atom. Hal ini dilakukan melalui operator pembanding berbasis CPU khusus (itulah sebabnya In-Memory hanya bekerja dengan prosesor [meskipun hampir semua CPU yang dibuat dalam 4 tahun terakhir] prosesor). Jadi kami tidak mendapatkan semuanya secara gratis, masih ada waktu untuk menyelesaikan operasi ini.
Hal lain yang perlu dikemukakan adalah kenyataan bahwa di hampir semua kueri, antarmuka yang digunakan adalah T-SQL (dan tidak secara alami mengkompilasi SPROCs) yang semuanya menyentuh setidaknya satu tabel berbasis disk. Inilah sebabnya saya percaya, pada akhirnya, kami tidak benar-benar mengalami peningkatan kinerja karena kami masih terkendala dengan kinerja tabel berbasis disk.
Mengikuti:
Buat sesi acara diperpanjang untuk wait_completed dan tentukan SPID yang Anda kenal. Jalankan kueri dan beri kami output atau konsumsi secara internal.
Beri kami pembaruan pada output dari # 1.
Tidak ada angka ajaib untuk menentukan jumlah bucket untuk indeks hash. Pada dasarnya selama ember tidak sepenuhnya penuh dan rantai baris tetap di bawah 3 atau 4, kinerja harus tetap dapat diterima. Ini seperti bertanya, "Apa yang harus saya atur file log saya?" - itu akan tergantung per proses, per database, per jenis penggunaan.
OPTION(OPTIMIZE FOR UNKNOWN)
(lihat Tabel Petunjuk )?