Есть ли прирост производительности при индексировании логического поля?

Я собираюсь написать запрос, включающий WHERE isok=1. Как следует из названия, isok - это логическое поле (фактически TINYINT(1) UNSIGNED, для которого установлено значение 0 или 1 по мере необходимости).

Есть ли прирост производительности при индексировании этого поля? Будет ли движок (в данном случае InnoDB) работать лучше или хуже при поиске по индексу?


person Niet the Dark Absol    schedule 09.05.2012    source источник
comment
возможный дубликат логических полей индексации   -  person Maxim Krizhanovsky    schedule 11.05.2012


Ответы (7)


Не совсем. Вы должны думать об этом как о книге. Если бы в книге было всего 3 вида слов и вы все их проиндексировали, у вас было бы такое же количество индексных страниц, как и у обычных страниц.

Было бы лучше, если бы было относительно мало записей с одним значением. Например, если у вас есть 1000 записей и 10 из них ИСТИНА, то было бы полезно, если вы выполняете поиск с помощью isok = 1

Как сказал Майкл Даррант, это также замедляет запись.

РЕДАКТИРОВАТЬ: возможное дублирование: Индексирование логических полей

Здесь объясняется, что даже если у вас есть индекс, если у вас слишком много записей, индекс все равно не используется. MySQL не использует индекс при проверке = 1 , но используя его с = 0

person Michael Koper    schedule 09.05.2012
comment
Похоже, да: 2 - нет: 1. Здесь кто-то не прав, но кто? - person Niet the Dark Absol; 10.05.2012
comment
Это не совсем правильно, без индекса mySql необходимо сканировать всю таблицу, чтобы найти соответствующие строки. - person ilanco; 10.05.2012
comment
в противном случае он будет сканировать весь индекс. (который в большинстве случаев такой же длинный) - person Michael Koper; 10.05.2012
comment
Спасибо за найденный дубликат - не видел его в связанных вопросах. Принято, потому что это помогло мне найти ответ :) - person Niet the Dark Absol; 10.05.2012
comment
Если логическое значение проиндексировано, оно будет сохранено в памяти, а если оно не проиндексировано, вам придется перейти на диск, который работает медленнее. - person Ed Massey; 18.11.2014
comment
Это может иметь значение. Просто сократите время выполнения на половину запроса, просто добавив индекс, и записи будут редкими и достаточно дешевыми, чтобы нас не волновали штрафы. Как и во всем, не предполагайте, измеряйте (также потому, что базы данных на самом деле не всегда ведут себя так, как вы логически ожидаете от них) - person Eelco; 09.03.2015
comment
Это предполагает равное распределение значений ИСТИНА и ЛОЖЬ. Как упоминается ниже @oucil, если вы ищете логическое значение, которое встречается довольно редко, это может занять некоторое время. Не говорю, что вы всегда должны индексировать, но я предполагаю, что характер ваших данных и ваших запросов также имеет значение для большинства движков баз данных. - person mahemoff; 28.09.2015
comment
@EdMassey - Нет, расположение в ОЗУ и на диске не так просто. Все блоки (данные или индекс) при необходимости кэшируются в buffer_pool. Таким образом, любой блок может находиться в памяти, а может и не находиться. - person Rick James; 13.12.2018
comment
Я думаю, это действительно зависит от того, что вы собираетесь делать. и как db хранит данные и как db собираются запускать sql (который зависит от dbs и выбора конфигурации). Не могу сказать, что это совершенно бесполезно. - person ; 21.01.2020

Просто чтобы уточнить несколько других ответов здесь, поскольку, по моему опыту, те, кто задает подобные вопросы, находятся в той же лодке, что и мы, мы все слышали, что индексирование логических полей бессмысленно, и все же ...

У нас есть таблица с примерно 4 миллионами строк, только около 1000 или около того за раз будут отмечены логическим переключателем, и это то, что мы ищем. Добавление индекса в наше логическое поле ускорило запросы на порядки, оно увеличилось с 9+ секунд до долей секунды.

person oucil    schedule 10.12.2013
comment
Да, хотя вы должны окончательно попытаться понять «почему» вещей, всегда измеряйте параллельно и пробуйте разные вещи в своем фактическом наборе данных, чтобы увидеть, совпадает ли ваша теория с фактическим поведением движка db (вы будете удивлены ... ) - person Eelco; 09.03.2015
comment
@Eelco Вы правы, но в этом случае результат действительно хорошо согласуется с основной теорией. Основная идея о том, что им следует пренебречь, имеет смысл только в том случае, если вы с вероятностью 50% встретите элементы, соответствующие вашему запросу. Затем, чтобы найти 100 совпадений, БД необходимо перебрать 200 элементов. Но если элементы совпадают только в 1% случаев, потребуется перебрать 10 000 элементов. - person mahemoff; 28.09.2015
comment
Мне нравится, когда люди действительно пробуют что-то на поле и дают обратную связь, а не просто философствуют. - person Viktor Joras; 25.06.2019
comment
WHERE my_col > 0 вместо my_col = 1 тоже, кажется, помогает ускорить - person Aaron; 22.09.2019

Это зависит от реальных запросов и избирательности комбинации индекса / запроса.

Случай A: условие WHERE isok = 1 и ничего другого:

SELECT *
FROM tableX
WHERE isok = 1
  • Если индекс достаточно избирательный (скажем, у вас 1 миллион строк и только 1 тысяча имеет isok = 1), то механизм SQL, вероятно, будет использовать индекс и будет работать быстрее, чем без него.

  • Если индекс недостаточно избирательный (скажем, у вас 1 миллион строк и более 100 тысяч имеют isok = 1), то механизм SQL, вероятно, не будет использовать индекс и выполнит сканирование таблицы.

Случай B: условие WHERE isok = 1 и многое другое:

SELECT *
FROM tableX
WHERE isok = 1
  AND another_column = 17

Затем это зависит от того, какие у вас есть еще индексы. Индекс на another_column, вероятно, будет более избирательным, чем индекс на isok, который имеет только два возможных значения. Индекс на (another_column, isok) или (isok, another_column) был бы даже лучше.

person ypercubeᵀᴹ    schedule 09.05.2012
comment
Думаю, это более правильный ответ по сравнению с верхним. также распределение данных. - person ; 21.01.2020

Это зависит от распределения данных.

Представьте, что у меня есть книга с 1000 тщательно напечатанными страницами, и единственными словами в моей книге были «да» и «нет», повторяющиеся снова и снова и распределяемые случайным образом. Если бы меня попросили обвести все «да», поможет ли указатель в конце книги? По-разному.

Если бы было половинное случайное распределение «да» и «нет», то поиск в индексе не помог бы. Индекс сделал бы книгу намного больше, и в любом случае я бы быстрее начал просто с лицевой стороны и пролистал каждую страницу, ища все вхождения `` да '' и обводя их, вместо того, чтобы искать каждый элемент в индекс, а затем взяв ссылку из записи индекса на страницу, на которую он ссылается.

Но если бы в моей тысячестраничной книге было, скажем, всего десять случаев «да», а все остальное было бы просто миллионами «нет», то указатель сэкономил бы мне массу времени, чтобы найти эти десять случаев «да» и обвести их кругом. .

То же самое и в базах данных. Если это распределение 50:50, то индекс не поможет - движку базы данных лучше просто пролистать данные от начала до конца (полное сканирование таблицы), а индекс просто сделает базу данных больше, и медленнее писать и обновлять. Но если это что-то вроде распределения 4000: 1 (согласно oucil в этом потоке), то поиск по индексу может значительно ускорить его, если это 1 элемент из 4000, который вы ищете .

person Jinlye    schedule 07.04.2017

Нет, обычно нет.

Обычно вы индексируете поля для поиска, когда они имеют высокую избирательность / количество элементов. Мощность логического поля в большинстве таблиц очень мала. Это также сделало бы вашу запись немного медленнее.

person Michael Durrant    schedule 09.05.2012

На самом деле это зависит от выполняемых вами запросов. Но, как правило, да, как и индексация поля любого другого типа.

person Maksym Polshcha    schedule 09.05.2012

Да, индекс повысит производительность, проверьте вывод EXPLAIN с индексом и без него.

Из документов:

Индексы используются для быстрого поиска строк с определенными значениями столбцов. Без индекса MySQL должен начать с первой строки, а затем прочитать всю таблицу, чтобы найти соответствующие строки. Чем больше таблица, тем дороже это стоит. Если таблица имеет индекс для рассматриваемых столбцов, MySQL может быстро определить позицию для поиска в середине файла данных, не просматривая все данные.

Я также думаю, что можно с уверенностью сказать, что в этом случае производительность индекса не будет УМЕНЬШИТЬ, поэтому вам нужно только получить от этого выгоду.

person ilanco    schedule 09.05.2012
comment
Индекс дает много данных на жестком диске и замедляет запись, поэтому вы не получаете от этого только выгоду. - person Michael Koper; 10.05.2012
comment
Верно, но в этом случае TINYINT(1) UNSIGNED столбец размер данных будет небольшим. - person ilanco; 10.05.2012
comment
И дополнительные накладные расходы на запись, вероятно, довольно низкие - person Eelco; 09.03.2015
comment
Разве размер индекса не будет расти вместе с количеством строк, на которые он указывает, а не только с размером индексированного поля? - person poolie; 09.05.2016