Які міркування щодо ефективності між використанням широкого ПК та окремого синтетичного ключа та UQ?


10

У мене є кілька таблиць, де записи можна однозначно ідентифікувати з кількома широкими сферами бізнесу. Раніше я використовував ці поля як ПК, маючи на увазі ці переваги:

  • Простота; немає сторонніх полів і лише один індекс
  • Кластеризація дозволяє швидко поєднувати з'єднання та фільтри на основі діапазону

Однак я чув випадок, створений для створення синтетичного IDENTITY INTПК, і замість цього виконувати діловий ключ з окремим UNIQUEобмеженням. Перевага полягає в тому, що вузький ПК створює значно менші вторинні показники.

Якщо таблиця не має індексів, окрім PK, я не бачу жодної причини надати перевагу другому підходу, хоча у великій таблиці, мабуть, найкраще припустити, що індекси можуть бути необхідними в майбутньому, а тому надають перевагу вузькому синтетичному ПК . Чи пропускаю я якісь міркування?

Між іншим, я не заперечую проти використання синтетичних ключів у сховищах даних, мене просто цікавить, коли використовувати єдиний широкий ПК та коли використовувати вузьку ПК та широку Великобританію.


1
ви можете виявити це чи це корисним серед інших питань на сайті
Джек каже спробувати topanswers.xyz

Відповіді:


11

Використання природного ключа як кластерного індексу не має суттєвого недоліку

  • немає некластеризованих індексів
  • немає сторонніх ключів, на які посилається ця таблиця (це батьківський рядок)

Недоліком було б збільшення розбиття сторінки, оскільки вставки даних будуть розподілятися по всій інформації, а не в кінці.

Якщо у вас є індекси FK або NC, то використання вузького числового, кластеризованого індексу має переваги. Ви повторюєте лише кілька байт даних на запис NC або FK, а не діловий / природний ключ.

Щодо того, прочитайте надто 5 статей від Google

Примітка. Я уникав використання "первинного ключа".

Ви можете мати кластерний індекс на сурогатному ключі, але зберігати ПК за діловими правилами, але як некластеризовані. Просто переконайтесь, що кластеризація унікальна, тому що SQL додасть "унікальний", щоб зробити це так.

Нарешті, можливо, має сенс мати сурогатний ключ, але не сліпо на кожному столі : багато-багатьох таблиць не потребують одного, або де достатньо складеного ключа з батьківських таблиць


+1 для довідки відмінні статті місіс Трипп в індексації.
Fabricio Araujo

2
+1 за те, що продуктивність не має нічого спільного з первинними ключами та все, що стосується індексів.
nvogel

4

Хоча я ризикую зазначити очевидне, індекс на сурогатному ключі (ідентифікаційний номер) корисний, якщо вам потрібно знайти речі за їх ідентифікаційним номером. Користувачі не збираються мати справу з ідентифікаційним номером; вони збираються мати справу з текстом, зрозумілим для людини. Тож вам доведеться дуже багато обходити текст та його ідентифікаційний номер, щоб користувальницький інтерфейс міг відображати текст та діяти на ідентифікаційному номері.

Dbms використовуватиме такий тип індексу для підтримки зовнішніх ключів, якщо ви їх визначаєте таким чином.

Іноді можна покращити продуктивність, використовуючи ідентифікаційні номери як сторонні ключі, але це не є абсолютним поліпшенням. У нашій системі OLTP зовнішні ключі, що використовують природні ключі, перевершують зовнішні ключі, використовуючи ідентифікаційні номери в тестовому наборі з приблизно 130 (я думаю) репрезентативних запитів. (Оскільки важлива інформація часто переноситься в клавішах, за допомогою природних клавіш уникнути великої кількості приєднань.) Середня швидкість прискорення склала 85 разів (приєднання за допомогою ідентифікаційних номерів займало 85 разів довше, щоб повернути рядки).

Тести показали, що приєднання до ідентифікаційних номерів не виконуватиметься швидше, ніж читання на природних ключах у нашій базі даних, поки певні таблиці не досягнуть мільйонів рядків. Ширина рядка має багато спільного з цим - ширші рядки означають, що менше рядків вміщується на сторінці, тому вам доведеться прочитати більше сторінок, щоб отримати 'n' рядки. Майже всі наші таблиці знаходяться в 5NF; більшість таблиць досить вузькі.

До того моменту, коли приєднання починають виконувати тут прості читання , розміщення критичних таблиць та індексів на твердотільному диску може вирівняти продуктивність у сотні мільйонів рядків.


3

У мене є ціла база даних oltp, створена з використанням стовпців ідентифікації для кластеризації + pk. Він працює досить швидко при вставці / пошуку, але я бачив кілька проблем:
1. Варіант заповнення індексу марний, оскільки вставки відбуваються лише до кінця індексу
2. більше місця для зберігання. У мене є таблиці з десятками мільйонів записів і 1 int займає простір сам по собі. Кожна таблиця зі стовпцем ідентичності для її pk повинна мати інший індекс для пошуку бізнесу, тому потрібно ще більше місця для зберігання.
3. масштабованість. Це найгірша проблема. Оскільки кожна вставка йде до кінця індексу, кожна вставка підкреслює лише кінець індексу (виділення, io для запису тощо). Використовуючи бізнес-ключ як кластерний ключ, ви можете розподілити вставки рівномірно по індексу. Це означає, що ви просто усунули велику точку доступу. Ви можете легко використовувати більше файлів для індексу, кожен файл на окремому диску, кожен диск працює окремо.

Я почав змінювати свої таблиці з стовпців ідентичності на природні ключі (можливо, окремі для кластеризації & pk). Просто зараз почувається краще.

Я б запропонував наступне (принаймні, для oltp db):
1. використовувати в якості кластеризації клавіші правильні стовпці в правильному порядку для оптимізації найчастіших запитів
2. використовувати pk правильні стовпці, які мають сенс для вас таблиці

Якщо кластерний ключ не є простим і містить символи (char [], varchar, nvarchar), я думаю, що відповідь - це "залежить", ви повинні проаналізувати окремо кожен випадок.

Я дотримуюся наступного принципу: оптимізуйте для найпоширенішого запиту, мінімізуючи найгірший сценарій.

Я майже забув один приклад. У мене є кілька таблиць, які посилаються на себе. Якщо в цій таблиці є стовпець ідентичності для її первинного ключа, то для вставки одного рядка може знадобитися оновлення, і вставляти більше одного рядка одночасно може бути важко, якщо не неможливо (це залежить від дизайну таблиці).


4
Твоя концепція "гарячої точки" - це міф: dba.stackexchange.com/questions/1584/… І коли ти кажеш "Зараз просто почувається краще". ти орієнтир?
gbn

4
Так, записи виконуються в пам'яті не безпосередньо на диску. Якщо ви пишете 20 нових рядків на сторінку, тоді лише один фізичний запис у файл даних, коли відбудеться контрольна точка.
mrdenny

@mrdenny з достатньою кількістю вставок, що записують усе до кінця індексу, надішле весь запит io на той самий файл. Я підозрюю, що за допомогою звичайних транзакцій oltp цей сценарій буде важко відтворити, але за допомогою деяких спеціальних сценаріїв, таких як вставка масових записів / пакетних записів, використання ssis для переміщення деяких бізнес-даних приведе вас туди.
Каталін Адлер

1
@ user973156 так, всі запити будуть виконуватись в одному файлі, але запис насправді не йде на диск, поки контрольна точка не відбувається щохвилини (за замовчуванням) або коли буфер запису заповнений на 50%. Не має значення, як ви записуєте дані, це правило все ще застосовується.
mrdenny

2
@ user973156 Використання довільно розподіленого ключа кластеризації буде викликати фрагментацію індексу. Фрагментація індексу БУДЕ викликати проблеми з продуктивністю І ваша таблиця вийде досить великою, що виконання дефрагментації індексу займе "тривалий час" і з'їдає простір журналу та потенційно tempDB простір. Коли у мене такі люди, як Кімберлі Тріпп, кажуть мені, що це гарна ідея, я слухаю. ( sqlskills.com/BLOGS/KIMBERLY/post/… )
Matt M

2

З точки зору продуктивності вибір клавіші "первинний" ключ взагалі не має значення. Немає різниці між використанням ОСНОВНОГО КЛЮЧА та УНІКАЛЬНОГО обмеження для виконання ваших ключів.

Продуктивність визначається вибором та типом індексів та інших варіантів зберігання та способом використання ключів у запитах та коді.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.