Кардинальність індексу: що вона означає

Автор: Опубліковано

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

Що саме означає кардинальність індексу

Індекс — це додаткова структура даних, яка полегшує пошук рядків без перегляду всієї таблиці. Його ключ — це значення одного стовпця або набір значень кількох стовпців. Кардинальність показує, скільки різних таких ключів є в даних, а не загальну кількість записів в індексі.

Припустімо, що таблиця kliienty має 100 000 рядків. Якщо кожен клієнт має окремий ідентифікатор, кардинальність індексу для стовпця id становить 100 000. Якщо стовпець status містить лише значення aktyvnyi, neaktyvnyi і zablokovanyi, його кардинальність становить 3.

Число, яке показують інструменти адміністрування, не завжди є точним результатом підрахунку даних. Рушій може визначати його на основі вибірки та зберігати у статистиці — відомостях про вміст таблиць, які використовуються для планування запитів. Як враховується значення NULL і як саме відображається кардинальність, слід перевірити в документації конкретного рушія.

Кардинальність і селективність запиту

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

Під час пошуку за одним унікальним ідентифікатором база може знайти один рядок. Для умови status = 'aktyvnyi' їй може знадобитися вибрати тисячі або десятки тисяч рядків. У другому випадку читання індексу з подальшим отриманням записів із таблиці може потребувати більше ресурсів, ніж повне сканування таблиці.

Проте сама кількість різних значень не показує, як часто трапляється кожне з них. Якщо 99 000 клієнтів активні, а лише 20 заблоковані, використання індексу для двох умов на тому самому стовпці може бути зовсім по-різному доцільним. Кардинальність усе ще становить 3, але розподіл даних нерівномірний.

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

Як розуміти кардинальність складеного індексу

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

Наприклад, таблиця може містити 10 країн і 500 різних пар «країна — місто». Тоді кардинальність першої частини ключа становить 10, а всього ключа — 500. Не слід автоматично множити кількість різних країн на кількість різних міст, адже не кожна можлива комбінація обов’язково є в таблиці.

Деякі інструменти показують окремі оцінки для послідовних початкових частин індексу. У MySQL поле Cardinality у результаті SHOW INDEX потрібно тлумачити разом із позицією стовпця, заданою в Seq_in_index: оцінка стосується префікса індексу, який закінчується на цій позиції.

Порядок стовпців також впливає на використання індексу. У типовому індексі B-tree, тобто індексі з упорядкованою деревоподібною структурою, ключ (kraina, misto) природно підтримує пошук за країною, а також за країною та містом. Пошук лише за містом може потребувати іншого способу доступу; доступні оптимізації залежать від рушія.

Чому високої кардинальності недостатньо

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

Важливо й те, як записано умову. Застосування функції до індексованого стовпця, наприклад виділення з дати лише року, може ускладнити використання звичайного індексу. Можливість застосувати функціональний індекс або відповідно переписати запит потрібно перевірити для конкретного рушія.

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

Як перевірити, чи допомагає індекс

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

  1. Виберіть типовий запит і репрезентативні значення параметрів, зокрема ті, що трапляються часто й рідко.
  2. Перевірте план виконання за допомогою EXPLAIN або відповідної команди вашого рушія.
  3. Зверніть увагу на вибраний індекс, оцінену кількість рядків і спосіб доступу до таблиці.
  4. Якщо це безпечно, порівняйте оцінки з фактичним виконанням. Пам’ятайте, що команди для аналізу виконання можуть запускати запит.
  5. Якщо розбіжності значні, перевірте актуальність статистики та правила її оновлення в документації бази даних.

Після масового імпорту, видалення записів або зміни розподілу значень статистика може не відображати поточні дані. Перш ніж додавати ще один індекс, перевірте план проблемного запиту та стан статистики — це допоможе відрізнити відсутність відповідного індексу від помилкової оцінки витрат.

Дивіться також: Що таке FireFox?

Читайте також

Дізнайтеся, як PHP-FPM обробляє запити PHP, чим відрізняється від вебсервера та як налаштувати процеси під трафік і ресурси хостингу.
Дізнайтеся, як BIND обслуговує DNS, чим відрізняються його серверні ролі та коли варто розгортати його самостійно замість керованої послуги.
Дізнайтеся, що означають польський реєстр і номер REGON, чим вони відрізняються від NIP та KRS і як перевірити дані підприємства.