Проблема индексации MYSQL - PullRequest
2 голосов
/ 05 марта 2012

У меня возникают трудности с поиском ответа на этот вопрос ... Для простоты давайте создадим эту ситуацию.

Я создаю такую ​​таблицу ..

CREATE TABLE `test` (
  `MerchID` int(10) DEFAULT NULL,
  KEY `MerchID` (`MerchID`) 
) ENGINE=InnoDB AUTO_INCREMENT=32769 DEFAULT CHARSET=utf8;

Я вставлю некоторые данные в столбец этой таблицы ...

INSERT INTO test
    SELECT 1
        UNION
    SELECT 2
        UNION
    SELECT null

Теперь я изучаю запрос, используя функцию объяснения MYSQL ...

EXPLAIN
SELECT * FROM test
WHERE merchid IS NOT NULL

Отдых в ID = 1 , SELECT_TYPE = SIMPLE , Таблица = тест , Тип = индекс , Possible_keys = MerchID , Ключ = MerchID , Key_len = 5 , Исх = NULL, , Строки = 3 , Extra = Использование где ; Используя индекс

В моей реальной работе что-то подобное занимает много времени с этим индексом. Если я объявляю таблицу со строкой индекса, читающей «KEY MerchID (MerchID) ИСПОЛЬЗУЯ BTREE», я получаю намного лучшие результаты. Функция объяснения, кажется, тоже возвращает те же результаты. Я прочитал некоторые основы о BTREE, Типы хранилища HASH и RTREE для индексов / ключей. Когда тип хранилища не указан, я отказался от предположения о том, что будет принят BTREE. Однако я несколько озадачен, почему при изменении моего индекса для использования этого типа хранилища моя процедура выглядит неэффективной. Любые идеи

Я использую MYSQL 5.1 и кодирую в MYSQL Workbench. Часть процедуры, которая, кажется, помогает, похожа на ту, что я иллюстрировал выше, где столбец объединенной таблицы проверяется на NULL.

Ответы [ 2 ]

2 голосов
/ 05 марта 2012

Я думаю, что вы на неправильном пути.Для хранилища InnoDB единственным доступным методом индекса является BTREE, поэтому, если вы можете опустить ключевое слово BTREE в скрипте создания таблицы. Поддерживаемые типы индексов здесь вместе с другой полезной информацией.

проблема производительности исходит из другого места.

0 голосов
/ 05 марта 2012

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

С индексом покрытия (все выбранные и отфильтрованные столбцы находятся в индексе) запрос достаточно эффективен.Using index в результате EXPLAIN показывает, что он используется в качестве индекса покрытия.

Однако, если бы индекс не был индексом покрытия, MySQL должен был бы выполнить поиск для каждой строки, возвращаемой индексомдля того, чтобы получить фактические данные таблицы.Хотя это будет быстро для небольшого набора результатов с набором результатов в 1 миллион строк, это будет 1 миллион запросов.Если бы число NULL-строк было большим процентом, MySQL вообще отказался бы от индекса, чтобы избежать поиска.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...