Почему MySQL не использует индекс для поля int, которое используется как логическое значение? - PullRequest
4 голосов
/ 24 декабря 2008
select * from myTable where myInt

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

Edit:
Указанный индекс не является уникальным.

Ответы [ 4 ]

5 голосов
/ 24 декабря 2008

Чтобы MySQL использовал индекс, необходимо явно сравнить поле int со значением (например, true, 1).

select * from myTable where myInt = true
2 голосов
/ 24 декабря 2008

Я не эксперт по базам данных, но разве это не умаляет цель иметь индекс для поля, если существует только два возможных значения поля?

Если все поля в индексированном столбце уникальны, ядро ​​базы данных может выполнить сканирование индекса, чтобы найти соответствующие строки. Если есть только два возможных значения - тогда я не вижу цели индексировать это поле. Механизм БД должен выполнить ту же операцию, что и при отсутствии индекса.

Возможно, MySQL не показывает его как возможный ключ, потому что движок отказался от идеи использования индекса в плане выполнения?

1 голос
/ 24 декабря 2008

Есть много факторов, которые следует учитывать.

Одним из факторов, которые не должны входить в него, является обозначение, используемое в вопросе. Если столбец является логическим значением, оптимизатор должен рассматривать эти условия как идентичные:

SELECT * FROM MyTable WHERE MyInt;

SELECT * FROM MyTable WHERE MyInt != 0;

SELECT * FROM MyTable WHERE MyInt IS TRUE;

SELECT * FROM MyTable WHERE MyInt = TRUE;

Могут быть и другие эквивалентные формулировки. Первый из них не является стандартным SQL (даже если тип MyInt является BOOLEAN; другие являются стандартными. Но оптимизатор должен просто преобразовать сокращение в соответствующую длинную форму и затем вести себя так же, как если бы длинная форма была написана пользователь. (Если оптимизатор не делает этого, то, возможно, существует проблема с оптимизатором; запрос должен быть сведен к канонической форме, прежде чем принимать решение о том, как обрабатывать запрос. Однако, даже в самых лучших оптимизаторах часто встречаются слепые зоны). Изучение того, как этого избежать, является искусством и присуще СУБД.)

Оптимизатор использует индекс, когда считает, что индекс повысит производительность запроса. Когда индекс не повышает производительность, он игнорируется (если оптимизатор хорош). Иногда это зависит от того, актуальна ли статистика для индекса.

В системах хранилищ данных система может быть спроектирована и настроена для очень быстрого последовательного сканирования таблицы; в таких системах, если селективность индекса такова, что при его использовании будет извлечено более 25% строк, на самом деле полное сканирование таблицы может быть быстрее, чем при использовании индекса.

Подумай об этом. При чтении по индексу СУБД должна выполнить как минимум два чтения; он считывает информацию о строке со страницы индекса, а затем должен прочитать строку со страницы данных.

Некоторые СУБД предоставляют таблицы только для индексов. Все данные в индексе. Другие СУБД предоставляют такой механизм, что вы можете сказать, что «индекс уникален для столбцов A, B, C; однако, включите столбцы D и E в данные». Затем, если для запроса требуются данные из A, B, C, D или E (или любой комбинации) и нет фильтрации по другим столбцам, СУБД должна только сканировать индекс, а не страницы таблиц.

Как правило, вы получаете много строк индекса на странице. Однако для некоторых таблиц чтение индекса может потребовать чтения большего количества данных, чем чтения строк. Рассмотрим архетипическую таблицу сопоставления «многие ко многим», содержащую два (4-байтовых) значения целочисленного идентификатора. Это требует 8 байтов на строку на страницах данных, но индекс, вероятно, требует 4-8 байтов служебной информации (поскольку запись ключа индекса хранит два значения идентификатора плюс информацию, необходимую для поиска соответствующей строки на диске). Таким образом, сканирование индекса может потребовать вдвое больше дискового ввода-вывода, чем сканирование данных, даже если сканирование индекса выполняется «только по индексу».

Это едва касается поверхности возможных причин использования или неиспользования индекса.

0 голосов
/ 24 декабря 2008

Мне кажется, что ваш вопрос SQL искажен. Вы ищете ненулевые значения столбца? Для этого следует использовать индекс:

select * from myTable where myInt is not null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...