Saya sedang membaca Clustered
dan Non Clustered Indexes
.
Clustered Index
- Ini berisi Halaman Data. Itu berarti informasi baris lengkap akan hadir di Kolom Indeks Clustered.
Non Clustered Index
- Ini hanya berisi informasi Row Locator dalam bentuk kolom Indeks Clustered (jika tersedia) atau File Indentifier + Nomor Halaman + Total Baris dalam Halaman. Ini berarti bahwa mesin kueri harus mengambil langkah tambahan untuk menemukan data aktual.
Kueri - Bagaimana saya dapat memeriksa perbedaan kinerja dengan bantuan contoh praktis seperti yang kita ketahui bahwa tabel hanya dapat memiliki satu Clustered Index
dan menyediakan sorting
di Clustered Index Column
dan Non Clustered Index
tidak menyediakan sorting
serta dapat mendukung 999 Non Clustered Indexes
in SQL Server 2008
dan 249 in SQL Server 2005
.
Jawaban:
Pertanyaan yang sangat bagus karena merupakan konsep yang sangat penting. Ini adalah topik besar dan apa yang akan saya tunjukkan kepada Anda adalah penyederhanaan sehingga Anda dapat memahami konsep dasarnya.
Pertama ketika Anda melihat tabel think index berkerumun . Dalam SQL server jika tabel tidak berisi indeks berkerumun itu adalah tumpukan. Membuat indeks berkerumun di atas meja sebenarnya mengubah tabel menjadi struktur tipe b-tree. Indeks berkerumun Anda adalah tabel Anda tidak terpisah dari tabel
Pernah bertanya-tanya mengapa Anda hanya dapat memiliki satu indeks berkerumun? Nah jika kita memiliki dua indeks berkerumun kita akan membutuhkan dua salinan tabel. Bagaimanapun juga, ini berisi data.
Saya akan mencoba dan menjelaskan ini dengan menggunakan contoh sederhana.
CATATAN: Saya membuat tabel dalam contoh ini dan mengisinya dengan lebih dari 3 juta entri acak. Kemudian jalankan pertanyaan aktual dan tempelkan rencana eksekusi di sini.
Apa yang benar-benar perlu Anda pahami adalah notasi O atau efisiensi operasional . Mari kita asumsikan Anda memiliki tabel berikut.
Jadi di sini kita memiliki tabel dasar dengan kunci berkerumun di CustomerID (Kunci primer dikelompokkan secara default). Dengan demikian tabel disusun / dipesan berdasarkan pada primaryID kunci Pelanggan. Level menengah akan berisi nilai-nilai CustomerID. Halaman data akan berisi seluruh baris sehingga merupakan baris tabel.
Kami juga akan membuat indeks non-cluster di bidang CustomerName. Kode berikut akan melakukannya.
Jadi dalam indeks ini Anda akan menemukan pada halaman data / tingkat daun node pointer ke tingkat menengah dalam indeks berkerumun. Indeks diatur / dipesan di sekitar bidang Nama Pelanggan. Dengan demikian tingkat menengah berisi nilai-nilai CustomerName dan tingkat daun akan berisi pointer (nilai-nilai pointer ini sebenarnya adalah nilai-nilai kunci utama atau kolom CustomerID).
Benar jadi jika kita menjalankan kueri berikut:
SQL mungkin akan membaca indeks berkerumun melalui operasi pencarian. Operasi pencarian adalah pencarian biner yang jauh lebih efisien daripada scan yang merupakan pencarian berurutan. Jadi dalam contoh kami di atas indeks dibaca dan dengan menggunakan pencarian biner, SQL dapat menghilangkan data yang tidak sesuai dengan kriteria yang kami cari. Lihat tangkapan layar terlampir untuk paket kueri.
Jadi jumlah operasi atau O Notasi untuk operasi pencarian adalah sebagai berikut:
Jadi ini adalah dua operasi. Namun jika kami menjalankan kueri berikut:
SQL sekarang akan menggunakan indeks non-clustered di CustomerName untuk melakukan pencarian. Namun karena ini adalah indeks non-clustered itu tidak berisi semua data di baris.
Jadi SQL akan melakukan pencarian di tingkat menengah untuk menemukan catatan yang cocok kemudian melakukan pencarian menggunakan nilai yang dikembalikan untuk melakukan pencarian lain pada indeks berkerumun (alias tabel) untuk mengambil data aktual. Ini kedengarannya membingungkan, saya tahu tetapi membaca terus dan semuanya akan menjadi jelas.
Karena indeks non-cluster kami hanya berisi bidang CustomerName (nilai-nilai bidang yang diindeks disimpan dalam node perantara) dan penunjuk ke data yang merupakan CustomerID, indeks tidak memiliki catatan Nama Pelanggan. Nama Pelanggan harus diambil dari indeks atau tabel berkerumun.
Saat menjalankan kueri ini, saya mendapatkan paket eksekusi berikut:
Ada dua hal penting yang perlu Anda perhatikan pada screenshot di atas
Mengapa SQL menyarankan indeks pada CustomerName lagi? Yah karena indeks hanya berisi CustomerID dan SQL CustomerName masih harus menemukan Nama Pelanggan dari tabel / indeks berkerumun.
Jika kami membuat indeks dan kami menyertakan kolom Nama Pelanggan di indeks SQL akan dapat memenuhi seluruh permintaan dengan hanya membaca indeks non-clustered. Inilah sebabnya mengapa SQL menyarankan saya mengubah indeks non-clustered saya.
Di sini Anda dapat melihat operasi tambahan yang perlu dilakukan SQL untuk mendapatkan kolom Nama Pelanggan dari kunci berkerumun
Dengan demikian jumlah operasi adalah sebagai berikut:
Itu adalah 4 operasi untuk mendapatkan nilai keluar. Dua kali jumlah operasi yang dibutuhkan dibandingkan dengan membaca indeks berkerumun. Menunjukkan kepada Anda bahwa indeks berkerumun Anda adalah indeks yang paling kuat karena berisi semua data.
Jadi hanya untuk memperjelas satu poin terakhir. Mengapa saya mengatakan bahwa pointer dalam indeks non-cluster adalah nilai kunci primer? Nah untuk menunjukkan bahwa node tingkat daun dari indeks non-clustered berisi nilai kunci primer saya mengubah permintaan saya ke:
Dalam kueri ini SQL dapat membaca CustomerID dari indeks non-clustered. Tidak perlu melakukan pencarian pada indeks berkerumun. Ini bisa Anda lihat dari rencana eksekusi yang terlihat seperti ini.
Perhatikan perbedaan antara permintaan ini dan permintaan sebelumnya. Tidak ada pencarian. SQL dapat menemukan semua data dalam indeks non-cluster
Mudah-mudahan Anda dapat mulai memahami bahwa indeks berkerumun adalah tabel dan indeks non-berkerumun JANGAN berisi semua data. Pengindeksan akan mempercepat pemilihan karena fakta bahwa pencarian biner dapat dilakukan tetapi hanya indeks berkerumun yang berisi semua data. Jadi pencarian pada indeks non-cluster hampir selalu menghasilkan nilai-nilai yang diambil dari indeks cluster. Operasi tambahan ini membuat indeks non-cluster kurang efisien daripada indeks cluster.
Semoga ini jelas. Jika ada yang tidak masuk akal silakan kirim komentar dan saya akan mencoba menjelaskan. Agak terlambat di sini dan otak saya merasa agak datar. Saatnya banteng merah.
sumber
"Ini berarti bahwa mesin query harus mengambil langkah tambahan untuk menemukan data aktual."
Belum tentu - jika indeks mencakup permintaan yang diberikan, tidak perlu melakukan perjalanan ke halaman data. Juga, dengan kolom yang disertakan, kolom tambahan dapat ditambahkan ke indeks non-cluster untuk membuatnya menutupi tanpa mengubah ukuran kunci.
Jadi jawaban utamanya adalah - Itu Tergantung (pada informasi yang jauh lebih banyak daripada yang dapat Anda bahas dalam satu pertanyaan) - Anda perlu memahami semua kemampuan indeks dan rencana pelaksanaan untuk kueri yang diberikan dapat berbeda dari harapan Anda.
Aturan umum yang saya miliki adalah bahwa tabel selalu memiliki indeks berkerumun (dan biasanya pada identitas atau GUID berurutan), tetapi indeks non-berkerumun ditambahkan untuk kinerja. Tapi selalu ada pengecualian - heap tables memiliki tempat, indeks cluster yang lebih luas punya tempat. Tampaknya indeks yang berlebihan yang lebih sempit agar sesuai dengan lebih banyak baris per halaman ada tempatnya. dll. dll
Dan saya tidak akan khawatir tentang batasan pada berbagai indeks yang diizinkan - itu hampir pasti tidak akan berperan dalam banyak contoh dunia nyata.
sumber
there are always exceptions
- terlalu banyak orang mengabaikan ini dan berpikir setiap indeks yang dikelompokkan harus menjadiint identity
apa pun yang terjadi.