Чи додавання індексу на бітову колонку значно сповільнює вставки?


11

У мене є таблиця з приблизно 1 мільйоном до 5 мільйонів записів. Невелика частина цих записів має один бітовий стовпець, встановлений на "TRUE". Потрібно швидко знайти ці записи. Я думаю, що цей індекс може пришвидшити пошук по цій колонці, але я боюся за ВСТУП. Звідси моє запитання.

База даних працює як сховище даних, тому існує багато SELECT і невеликих (до 10-20 на день), але досить великих ВСТАВКИ (до 200 тисяч записів одночасно). Я боюся, що довший час цього імпорту в базу даних.


5
Яка версія SQL Server? Якщо 2008+ звучить як відфільтрований індекс, це може бути те, що вам потрібно.
— Мартін Сміт

SQL Server 2005
— маріош

1
Ви можете розділити таблицю (додайте нову таблицю лише з одним стовпцем, ПК таблиці, яка буде заповнена лише тими рядками, у яких стовпчик бітів є істинним - врешті-решт, ви навіть можете видалити бітовий стовпчик.) Зрозуміло б, як і в 2005 році, відсутність часткових індексів.
— ypercubeᵀᴹ

будьте обережні з індексованим видом, як ви згадали, у вас є 10-20 великих вставок на день, підтримка індексованого перегляду може перевершити користь від підвищення продуктивності. Я не думаю, що будь-яку "поза коробкою" функцію SQL 2005 ви можете використовувати для покращення своєї ситуації. але якщо ви перерахуєте поточну структуру таблиці та існуючий індекс, ми можемо знайти альтернативний дизайн.
— Ануп Шах

Відповіді:


8

Індекс на біт на 1 мільйон записів марний. Оптимізатор ніколи його не використовуватиме, ви просто заплатите за його підтримку. Набагато кращою альтернативою є додавання цього біта як лівої клавіші кластерного індексу.

Але я зроблю сліпий знімок у темряві і здогадуюсь, що у вас є шаблон черги: записи записуються в таблицю з бітом, встановленим на "TRUE" (тобто 'needprocessing = true'), і тоді фоновий процес виглядає для цих записів виконує деяку обробку та оновлює біт на FALSE. Це всюдисущий шаблон, який також ласкаво знають як "шаблон рецепта катастрофи". Я б рекомендував скинути записи в таблицю і одночасно скинути сповіщення (може бути таким же простим, як і щойно вставлений ідентифікатор запису), у чергу . Див. Розділ Використання таблиць як черг .


1
Я не бачу жодного сенсу розміщувати стовпчик бітів на самій лівій стороні, оскільки ми не знаємо інших фільтр-стовпців з високим користувачем Cardinalality. поки що я бачив, що стовпець BIT - це останній вибір у кластерному індексі. але так, +1 для приємного посилання на "Використання таблиці як черг".
— Ануп Шах

2
Насправді я провів тест, і так, він буде використовувати індекс. Створіть таблицю (Id ідентифікатор, біт myBit) додайте 100 рядків, де біт дорівнює 0, і 2000000, де біт 1. Переконайтесь, що статистика оновлюється (при необхідності) та запустіть запит на myBit = 0, і буде використаний індекс.
— Кеннет Фішер

@KennethFisher за винятком того, що в типовій схемі високої швидкості вставляти TRUE / update до FALSE негайно статистика завжди буде застарілою. Якщо ви віддаєте перевагу грати в російську рулетку з оптимізатором, а не робити чіткий дизайн, ви отримаєте те, чого заслуговуєте ...
— Рем Русану

"Ніколи не використовую", що заява стосується 99% випадків, але ми не знаємо, в якому випадку знаходиться ОП. Я успішно індексується на біт. Випадки використання існують.
— usr

питання - чи не відповідає тут відповідь , зокрема> "Коли ви індексуєте бітове поле (або якийсь вузький діапазон), ви лише зменшите робочий набір на кількість рядків, що відповідають цьому значенню. Якщо у вас є невелика кількість рядків, що відповідають цьому це значно зменшить ваш робочий набір . Для великої кількості рядків з розподілом 50/50 це може придбати вам дуже малий приріст продуктивності порівняно з постійним оновленням індексу ". У такому випадку індекс на біт, який відповідає 1% записів, позбавить потреби сканувати 99% з 1 мільйона для значного збільшення?
— drzaus

2

Як сказав @MartinSmith, якщо ви коли-небудь перейдете до SQL 2008, то відфільтрований індекс стане ідеальним рішенням. Однак середній час, як загальний випадок, будь-який доданий індекс збільшить ваш час завантаження. Малі показники менше, ніж великі.

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

Наступне, на що слід звернути увагу: "У мене вже багато індексів?" Немає жорсткого і швидкого правила щодо того, що таке "багато", але я зазвичай переходжу за правилом 10 індексів - це межа, якщо мені дійсно не потрібен новий.

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

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

Редагувати:

Інший варіант - розділити вашу таблицю. Можливо, вам доведеться використовувати розділений вигляд, якщо ви не використовуєте Enterprise Edition, але навіть це повинно допомогти. Ви ставите свої бітові 0 в один розділ, а свої бітові - в інші. Якщо припустити, що ви вставляєте лише одну чи іншу версію, то ви навіть можете пришвидшити свої вставки.

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