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

Apa praktik terbaik untuk menggunakan GUID sebagai kunci utama, khususnya terkait kinerja?

GUID tampaknya menjadi pilihan alami untuk kunci utama Anda - dan jika Anda benar-benar harus melakukannya, Anda mungkin dapat berdebat untuk menggunakannya untuk KUNCI UTAMA tabel. Yang sangat saya sarankan untuk tidak dilakukan menggunakan kolom GUID sebagai kunci pengelompokan , yang dilakukan SQL Server secara default, kecuali jika Anda secara khusus melarangnya.

Anda benar-benar harus memisahkan dua masalah:

  1. kunci utama adalah konstruksi logis - salah satu kunci kandidat yang secara unik dan andal mengidentifikasi setiap baris dalam tabel Anda. Ini bisa apa saja, sungguh - sebuah INT , sebuah GUID , sebuah string - pilih yang paling masuk akal untuk skenario Anda.

  2. kunci pengelompokan (kolom atau kolom yang mendefinisikan "indeks berkerumun" pada tabel) - ini adalah fisik hal terkait penyimpanan, dan di sini, tipe data kecil, stabil, dan terus meningkat adalah pilihan terbaik Anda - INT atau BIGINT sebagai opsi default Anda.

Secara default, kunci utama pada tabel SQL Server juga digunakan sebagai kunci pengelompokan - tetapi itu tidak harus seperti itu! Saya pribadi telah melihat peningkatan kinerja besar-besaran ketika memecah Kunci Utama/Kluster berbasis GUID sebelumnya menjadi dua kunci terpisah - kunci utama (logis) pada GUID, dan kunci pengelompokan (pemesanan) pada INT IDENTITY(1,1) kolom.

Seperti yang dikatakan Kimberly Tripp - Ratu Pengindeksan - dan lainnya berkali-kali - sebuah GUID karena kunci pengelompokan tidak optimal, karena karena keacakannya, ini akan menyebabkan fragmentasi halaman dan indeks yang besar dan kinerja yang umumnya buruk.

Ya, saya tahu - ada newsequentialid() di SQL Server 2005 dan lebih tinggi - tetapi bahkan itu tidak benar-benar dan sepenuhnya berurutan dan dengan demikian juga mengalami masalah yang sama dengan GUID - hanya sedikit kurang menonjol.

Lalu ada masalah lain yang perlu dipertimbangkan:kunci pengelompokan di atas meja akan ditambahkan ke setiap entri di setiap indeks non-cluster di meja Anda juga - jadi Anda benar-benar ingin memastikannya sekecil mungkin. Biasanya, sebuah INT dengan 2+ miliar baris seharusnya cukup untuk sebagian besar tabel - dan dibandingkan dengan GUID sebagai kunci pengelompokan, Anda dapat menghemat ratusan megabita penyimpanan di disk dan di memori server.

Perhitungan cepat - menggunakan INT vs. GUID sebagai Kunci Utama dan Pengelompokan:

  • Tabel Dasar dengan 1.000'000 baris (3,8 MB vs. 15,26 MB)
  • 6 indeks nonclustered (22,89 MB vs. 91,55 MB)

TOTAL:25 MB vs. 106 MB - dan itu hanya di satu meja!

Lebih banyak bahan untuk dipikirkan - hal-hal luar biasa oleh Kimberly Tripp - baca, baca lagi, cerna! Ini adalah Injil pengindeksan SQL Server, sungguh.

  • GUID sebagai PRIMARY KEY dan/atau kunci yang dikelompokkan
  • Perdebatan indeks berkerumun berlanjut
  • Kunci pengelompokan yang terus meningkat - Debat Indeks Tergugus..........sekali lagi!
  • Ruang disk murah - itu tidak intinya!

PS:tentu saja, jika Anda hanya berurusan dengan beberapa ratus atau beberapa ribu baris - sebagian besar argumen ini tidak akan terlalu berdampak pada Anda. Namun:jika Anda masuk ke dalam puluhan atau ratusan ribu baris, atau Anda mulai menghitung dalam jutaan - lalu poin-poin tersebut menjadi sangat krusial dan sangat penting untuk dipahami.

Pembaruan: jika Anda ingin memiliki PKGUID kolom sebagai kunci utama Anda (tetapi bukan kunci pengelompokan Anda), dan kolom lain MYINT (INT IDENTITY ) sebagai kunci pengelompokan Anda - gunakan ini:

CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
 MyINT INT IDENTITY(1,1) NOT NULL,
 .... add more columns as needed ...... )

ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)

CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)

Pada dasarnya:Anda hanya perlu secara eksplisit beri tahu PRIMARY KEY batasan bahwa itu NONCLUSTERED (jika tidak, itu dibuat sebagai indeks berkerumun Anda, secara default) - dan kemudian Anda membuat indeks kedua yang didefinisikan sebagai CLUSTERED

Ini akan berfungsi - dan ini adalah opsi yang valid jika Anda memiliki sistem yang ada yang perlu "direkayasa ulang" untuk kinerja. Untuk sistem baru, jika Anda memulai dari awal, dan Anda tidak berada dalam skenario replikasi, maka saya akan selalu memilih ID INT IDENTITY(1,1) sebagai kunci utama berkerumun saya - jauh lebih efisien daripada yang lainnya!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dapatkan daftar tanggal antara dua tanggal menggunakan fungsi

  2. Konfigurasi Replikasi Transaksional SQL Server

  3. Agregat bitwise-ATAU dalam subquery

  4. Bagaimana ISNUMERIC() Bekerja di SQL Server

  5. Cara Memperbaiki "Nama objek tidak valid 'OPENJSON'." di SQL Server