it-swarm.asia

Kapan kunci primer harus dinyatakan non-cluster?

Saat membuat database uji untuk pertanyaan lain yang saya tanyakan sebelumnya, saya ingat tentang Kunci Utama yang dapat dideklarasikan NONCLUSTERED

Kapan Anda akan menggunakan kunci primer NONCLUSTERED sebagai ganti dari kunci primer CLUSTERED?

Terima kasih sebelumnya

177
Stuart Blackler

Pertanyaannya bukan 'kapan PK harus NC', tetapi Anda harus bertanya 'apa kunci yang tepat untuk indeks berkerumun'?

Dan jawabannya sangat tergantung pada bagaimana Anda meminta data. Indeks berkerumun memiliki keunggulan dibandingkan semua indeks lain: karena selalu mencakup semua kolom, selalu mencakup. Oleh karena itu pertanyaan yang dapat memanfaatkan indeks berkerumun tentu tidak perlu menggunakan pencarian untuk memenuhi beberapa kolom yang diproyeksikan dan/atau predikat.

Bagian lain dari teka-teki adalah bagaimana indeks dapat digunakan? Ada tiga pola khas:

  • probe, ketika nilai kunci tunggal dicari dalam indeks
  • pemindaian rentang, ketika rentang nilai kunci diambil
  • memesan dengan persyaratan, ketika indeks dapat memenuhi pesanan dengan w/o membutuhkan semacam stop-and-go

Jadi, jika Anda menganalisis beban yang diharapkan (kueri) dan menemukan bahwa sejumlah besar kueri akan menggunakan indeks tertentu karena mereka menggunakan pola akses tertentu yang diuntungkan dari indeks, masuk akal untuk mengusulkan indeks itu sebagai indeks berkerumun.

Namun faktor lain adalah bahwa kunci indeks berkerumun adalah kunci pencarian yang digunakan oleh semua indeks non-clustered dan oleh karena itu kunci indeks clustered luas menciptakan efek riak dan memperluas semua indeks non-clustered dan indeks lebar rata-rata berarti lebih banyak halaman, lebih banyak I/O, lebih banyak memori, lebih sedikit kebaikan.

Indeks berkerumun yang baik adalah stabil, itu tidak berubah selama masa entitas, karena perubahan dalam nilai-nilai kunci indeks berkerumun berarti baris harus dihapus dan dimasukkan kembali.

Dan indeks cluster yang baik tumbuh agar tidak secara acak (setiap nilai kunci yang baru dimasukkan lebih besar dari nilai sebelumnya) untuk menghindari pemisahan halaman dan fragmentasi (tanpa mengacaukan FILLFACTORs).

Jadi sekarang kita tahu apa kunci indeks berkerumun yang baik, apakah kunci utama (yang merupakan properti logis pemodelan data) cocok dengan persyaratan? Jika ya, maka PK harus dikelompokkan. Jika tidak, maka PK harus non-cluster.

Untuk memberikan contoh, pertimbangkan tabel fakta penjualan. Setiap entri memiliki ID yang merupakan kunci utama. Tetapi sebagian besar kueri meminta data antara tanggal dan tanggal lain, oleh karena itu kunci indeks terkelompok terbaik adalah penjualan tanggal, bukan ID . Contoh lain dari memiliki indeks pengelompokan berbeda dari kunci primer adalah kunci selektivitas yang sangat rendah, seperti 'kategori', atau 'keadaan', kunci dengan hanya beberapa nilai berbeda. Memiliki kunci indeks yang dikelompokkan dengan kunci selektivitas rendah ini sebagai kunci paling kiri, mis. (state, id), seringkali masuk akal karena pemindaian rentang yang mencari semua entri dalam 'keadaan' tertentu.

Satu catatan terakhir tentang kemungkinan kunci primer non-clustered atas heap (mis. Tidak ada indeks clustered sama sekali). Ini mungkin skenario yang valid, alasan khasnya adalah ketika kinerja penyisipan massal sangat penting, karena tumpukan memiliki throughput penyisipan massal yang jauh lebih baik bila dibandingkan dengan indeks yang dikelompokkan.

194
Remus Rusanu

Alasan dasar untuk menggunakan indeks Clustered dinyatakan pada Wikipedia :

Clustering mengubah blok data ke dalam urutan berbeda tertentu untuk mencocokkan indeks, menghasilkan data baris yang disimpan secara berurutan. Oleh karena itu, hanya satu indeks berkerumun dapat dibuat pada tabel database yang diberikan. Indeks yang dikelompokkan dapat sangat meningkatkan kecepatan pengambilan secara keseluruhan, tetapi biasanya hanya di mana data diakses secara berurutan di tempat yang sama atau urutan terbalik dari indeks berkerumun , atau ketika berbagai item dipilih.

Katakan bahwa saya memiliki tabel Orang, dan orang-orang ini memiliki kolom Negara dan Kunci Utama yang unik. Ini adalah tabel demografi, jadi ini adalah satu-satunya hal yang saya pedulikan; Negara apa dan berapa banyak orang unik yang terikat pada negara itu.

Dengan demikian, saya hanya akan cenderung untuk MEMILIH DI MANA atau PESANAN DENGAN kolom Negara; indeks berkerumun pada Kunci Utama tidak ada gunanya bagiku, aku tidak mengakses data ini dengan PK, aku mengaksesnya dengan kolom lain ini. Karena saya hanya dapat memiliki satu indeks berkerumun di atas meja, menyatakan PK saya sebagai Berkelompok akan mencegah saya menggunakan Indeks Berkelompok di Negara.

Selain itu, inilah artikel bagus tentang Clustered vs Nonclustered Indexes , ternyata indeks clustered menyebabkan masalah kinerja penyisipan di SQL Server 6.5 (yang setidaknya semoga tidak relevan bagi kebanyakan dari kita di sini).

Jika Anda meletakkan indeks berkerumun pada kolom IDENTITY, maka semua sisipan Anda akan terjadi pada halaman terakhir tabel - dan halaman itu dikunci selama durasi setiap IDENTITY. Bukan masalah besar ... kecuali jika Anda memiliki 5000 orang yang semuanya menginginkan halaman terakhir. Maka Anda memiliki banyak pertengkaran untuk halaman itu

Perhatikan bahwa ini tidak terjadi di versi yang lebih baru.

27
Ben Brocka

Jika kunci utama Anda adalah UNIQUEIDENTIFIER, pastikan untuk menentukan bahwa itu NONCLUSTERED. Jika Anda membuatnya berkerumun, setiap sisipan harus melakukan banyak pengocokan catatan untuk menyisipkan baris baru di posisi yang benar. Ini akan menurunkan kinerja.

17
Bryan Johns

Contoh yang sangat umum:

  • Customer tabel dengan CustomerID sebagai CLUSTERED PRIMARY KEY
  • Tabel pesanan dengan OrderID (PK), CustomerID, OrderDate dan beberapa kolom lainnya
  • OrderPositions dengan OrderPositionID (PK), OrderId, ProductID, Amount, Price ...
  • anda harus mengindeks tabel Orde

Tentu saja "itu tergantung" adalah - seperti hampir selalu - jawaban yang benar, tetapi sebagian besar aplikasi (bukan BI-Laporan) akan berfungsi berdasarkan pelanggan (misalnya Anda login sebagai pelanggan 278 ke situs web dan klik ke "Pesanan saya" atau Petugas mendaftarkan semua pesanan untuk pelanggan 4569 atau rutin faktur Anda akan meringkas semua pesanan untuk pelanggan 137).

Dalam hal ini tidak masuk akal untuk mengelompokkan tabel dengan OrderID. Ya, Anda akan memiliki kueri sebagai SELECT ... WHERE OrderId = ? Untuk mendaftar detail pesanan, tetapi biasanya indeks pendek dan murah (3 kali dibaca) dicari.

Di sisi lain, jika Anda akan mengelompokkan tabel Order Anda dengan CustomerID, itu tidak harus melakukan beberapa pencarian kunci setiap kali Anda meminta tabel untuk CustomerId = ?.

The CLUSTERED INDEX Harus selalu UNIQUE, jika tidak, SQL Server akan menambahkan kolom INT yang tidak terlihat (= tidak dapat digunakan) UNIQUIFIER untuk memastikan keunikan - dan akan lebih masuk akal untuk menambahkan data real (dapat digunakan) kemudian beberapa hal acak (tergantung pada urutan penyisipan).

Karena pelanggan akan (semoga) melakukan lebih dari satu pesanan, kami harus menambahkan OrderID atau (jika Anda biasanya mengurutkan untuk ini) OrderDate (jika ini adalah waktu - pelanggan akan dibatasi untuk satu pesanan per hari) ke CLUSTERED INDEX dan berakhir dengan:

CREATE UNIQUE CLUSTERED INDEX IX_Orders_UQ on Orders (CustomerID, OrderID)

Aturan yang sama berlaku untuk tabel OrderPositions. Biasanya pertanyaan paling banyak akan mencantumkan semua posisi untuk urutan tertentu, jadi Anda harus membuat PK dengan OrderPositionID sebagai NONCLUSTERED dan UNIQUE CLUSTERED INDEX Pada OrderId, OrderPositionID.

BTW: benar bahwa tabel Customer dikelompokkan oleh PK-nya (CustomerID, karena ini adalah "Top-Level-Table" dan akan - dalam aplikasi yang khas - sebagian besar ditanyai oleh CustomerID-nya.

Tabel pencarian murni seperti mis. Genders atau InvoiceTypes atau PaymentType adalah contoh lain dari tabel yang harus dikelompokkan dengan PK-nya (karena biasanya Anda akan bergabung dengan mereka di GenderId, InvoiceTypeId atau PaymentTypeId).

8
Thomas Franz

Ketika indeks berkerumun dianggap lebih bermanfaat bagi sistem keseluruhan daripada PK berkerumun dengan menggunakan beberapa ukuran kinerja. Hanya ada satu indeks berkerumun di atas meja.

Contoh ukuran kinerja adalah waktu kueri tunggal (kecepatan), integrasi waktu kueri total terhadap tabel (efisiensi) dan harus menambahkan banyak kolom termasuk ke indeks non-cluster yang sangat besar untuk mencapai kinerja yang mirip dengan clustered (ukuran ).

Ini bisa terjadi ketika data umumnya diambil menggunakan indeks yang tidak unik, berisi nol (tidak diizinkan dalam PK), atau PK ditambahkan untuk alasan sekunder (seperti replikasi atau identifikasi catatan jejak audit).

2
crokusek