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


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.