Цю сторінку перекладено машинним перекладом. Читайте англійський оригінал. English

Бібліотека IBSurgeon

Різниця між полями VARCHAR та INTEGER у ключах

Я використовую цілочисельні ID для первинних ключів у своїх таблицях. Що як я замість цього використаю поля varchar? Чи втрачу я продуктивність у такому випадку, особливо для великих таблиць? Чи будуть з’єднання працювати так само швидко, як і для цілочисельної колонки?

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

Ключ з одного поля спочатку перетворюється на один із трьох канонічних типів: рядок із колацією, double precision і (на жаль) 64-бітне ціле число. Дати перетворюються на числа з плаваючою комою double precision.

Рядки, які мають колацію, відмінну від їхнього байтового значення, перетворюються у формат своєї колації. Це свого роду чорна магія, яка збільшує розмір рядка, але результатом є те, що рядок знаходить своє правильне місце при сортуванні з іншими рядками тієї ж колації. ‘A’, ‘a’, ‘â’, ‘á’, ‘Ă’, ‘ã’, ‘ä’, ‘å’, ‘ă’, ‘ą’, ‘Ā’ - усі з’являються на своїх призначених місцях. (Вибачте за те, що це зробило з вашим поштовим клієнтом… у моєму це одинадцять варіантів літери ‘A’.) Кінцеві пробіли не включаються в ключ.

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

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

Складені ключі майже такі самі. Кожна частина перетворюється на свій тип ключа індексу та доповнюється до кратного 4 байтам. Після кожних чотирьох байтів Firebird додає байт із позицією поточного поля ключа. Таким чином, індекс на LastName, FirstName, ZodiacSign виглядав би як 1Harr1ison2Ann 3Gemi3ni. Це дозволяє уникнути плутанини між Damnation і Dam nation.

Чому я сказав “(на жаль)” вище? Тому що наявність єдиного формату для чисел дозволяє Firebird змінювати розмір чисел без перестворення індексів на них. Але коли Borland повернув 64-бітні цілі числа - InterBase мав 64-бітні цілі числа з самого початку на Vaxes - якийсь розумник зрозумів, що double precision має 56 бітів точності, а 64-бітні цілі числа мають 64 біти. З іншого боку, індекси Firebird розроблені для роботи з деякою неточністю… або решту 8 бітів можна було б прикріпити в кінці… байдуже. Тому вам доводиться перебудовувати індекси при переході з Numeric/Decimal 9 на Numeric/Decimal 12. Сумно.

“Префіксне стиснення?” При зберіганні ключа, який не є першим на сторінці або першим після переходу на сторінці, Firebird дивиться на попередній ключ і відтинає ту частину початку наступного ключа, яка дублює попередника, і додає довжину відтятої частини на початку. Таким чином, рядки “AAAA”, “AAAB”, “AAAC”, “AABC” стають

“AAAA”, “3B”, “3C” та “2BC”. Існує проблема з деякими форматами GUID, які ставлять мінливу частину числа першою, а фіксовану частину - за нею. Це зводить нанівець префіксне стиснення та роздуває розмір індексів.

“Перехід?” - Префіксне стиснення значно зменшує розмір індексів, зменшуючи введення/виведення, але вимагає читання всієї сторінки для розшифрування ключа. Це добре для сторінок 1K, але з більшими розмірами сторінок обчислення були неприйнятними. Тому кожна сторінка індексу тепер має власний індекс, який вказує на зміщення нестиснених записів. Цей індекс називається вектором переходів.

Ann Harrision