Поміркуйте, що таке індекс у SQL - а індекс - це дійсно шматок пам’яті, що вказує на інші шматки пам’яті (тобто вказівники на рядки). Індекс розбивається на сторінки, щоб частини індексу можна було завантажувати та вивантажувати з пам'яті залежно від використання.
Коли ви запитуєте набір рядків, SQL використовує індекс, щоб знайти рядки швидше, ніж сканування таблиці (дивлячись на кожен рядок).
SQL має кластерні та некластеризовані індекси. Я розумію кластерні індекси, що вони групують схожі значення індексу на одній сторінці. Таким чином, коли ви запитуєте всі рядки, що відповідають значенню індексу, SQL може повернути ці рядки з кластерної сторінки пам'яті. Ось чому спроба кластерного індексу колонки GUID є поганою ідеєю - ви не намагаєтеся кластеризувати випадкові значення.
Коли індексується цілий стовпець, індекс SQL містить набір рядків для кожного значення індексу. Якщо у вас діапазон від 1 до 10, то у вас буде 10 покажчиків. Залежно від того, скільки рядків існує, це може бути по-різному. Якщо ваш запит шукає індекс, що відповідає "1", а там, де Ім'я містить "Fred" (припускаючи, що стовпець Ім'я не індексується), SQL дуже швидко отримує набір рядків, що відповідають "1", а потім сканує таблицю, щоб знайти решту.
Отож, що насправді робить SQL - це намагатися зменшити робочий набір (кількість рядків), який він повинен повторити.
Коли ви індексуєте бітове поле (або якийсь вузький діапазон), ви зменшуєте лише робочий набір на кількість рядків, що відповідають цьому значенню. Якщо у вас невелика кількість рядків, це збільшить ваш робочий набір значно. Для великої кількості рядків з розподілом 50/50 це може придбати вам дуже низький приріст продуктивності порівняно з постійним оновленням індексу.
Причина, по якій усі говорять про тестування, полягає в тому, що SQL містить дуже розумний і складний оптимізатор, який може ігнорувати індекс, якщо він вирішить, що сканування таблиці швидше, або може використовувати сортування, або організовувати сторінки пам'яті, однак це добре любить.