Задавайте вопросы, мы ответим
Вы не зашли.
MySQL 5.0.92-log
Есть таблица
CREATE TABLE `users` (
/* МНОГО ПОЛЕЙ */
PRIMARY KEY (`user_id`),
KEY `indx_user_session_time` (`user_session_time`),
KEY `indx_user_active` (`user_active`),
KEY `indx_user_lastvisit` (`user_lastvisit`),
KEY `indx_user_regdate` (`user_regdate`),
KEY `indx_user_from` (`user_from`),
KEY `indx_user_email` (`user_email`),
KEY `indx_user_posts` (`user_posts`),
KEY `indx_user_website` (`user_website`),
KEY `indx_username` (`username`),
KEY `indx_user_lastvisit__user_birthday__username` (`user_lastvisit`,`user_birthday`,`username`),
KEY `indx_user_weblog` (`user_weblog`)
) ENGINE=InnoDB DEFAULT CHARSET=cp1251
В ней первичный ключ и 11 вторичных.
Я знаю, что максимальная длина префиксов в innoDB не должна превышать 767 байт.
В этой таблице суммарная длина ключей явно меньше этого значения.
У меня был оптимизирован запрос на соединение с этой таблицей по индексу KEY `indx_user_weblog` (`user_weblog`), где user_weblog это INT(10).
На сколько я знаю, чем выше cardinality, тем лучше оптимизирован join. Всё хорошо. Cardinality был более 10000, точно не вспомню.
Но я создаю очередной индекс для VARCHAR(40)
KEY `indx_user_website` (`user_website`)
и cardinality KEY `indx_user_weblog` (`user_weblog`) резко падает до одного, двух. Естественно, в запросе join этот индекс перестал использоваться оптимизатором и он работает ужасно. Ключ также не используется, если применить USE INDEX или FORCE INDEX.
По правде говоря, поначалу длина VARCHAR была 100 для нескольких полей для которых были созданны индексы.
Это user_email, user_from, user_website.
То есть длина индексов была
`indx_user_session_time` - 4
`indx_user_active` - 3
`indx_user_lastvisit` - 4
`indx_user_regdate` - 4
`indx_user_from` - 103
`indx_user_email` - 103
`indx_user_posts` - 3
`indx_user_website` - 103
`indx_username` - 27
`indx_user_lastvisit__user_birthday__username` - 35
`indx_user_weblog` - 4
То есть явно меньше 767.
Но в торопях, я подумал, что больше, погорячился, уменьшил значения всех VARCHAR до 40.
Но дело было не в этом и это не помогло.
В итоге, я начал пересоздавать индексы и обнаружил, что теряет cardinality ПРЕДпоследний созданный индекс, причём если создаются все индексы, то есть его как бы выбивает почему-то последний созданный индекс.
Если не создаётся хотя бы один из списка (хотя проверял не по всем), то cardinality у всех в норме.
Я остановился на том, что создал предпоследним индекс `indx_user_website` , для которого теперь вычисляемый cardinality через SHOW INDEX FROM равен 1.
Но это поле не участвует в join-запросах, поэтому мне не страшно. Хотя этот индекс по-прежнему хорошо отрабатывает в обычном запросе на одну таблицу.
Вопрос, с чем связанно такое странное поведение? Может я упустил какой-то абзац в документации?
Отредактированно usershift (17.03.2011 01:52:33)
Неактивен
Возможно, я сделал преждевременные выводы. Нужный индекс всё равно отвалился. Cardinality возвращается на место после перестройки индекса. В чём может быть проблема?
Неактивен
http://bugs.mysql.com/bug.php?id=36513
Временно решил проблему, изменив движок таблицы на MyISAM.
Неактивен
Какая неприятная штука Но выглядит и правда как ошибка. Попробуйте хотя
бы 5.1 + innodb_plugin. Хотя, можно и 5.5 сразу.
Неактивен
Спасибо, что ответили.
Есть ещё такой параметр
innodb_use_legacy_cardinality_alghoritm , который по-умолчанию ON, то есть используется унаследованный алгоритм и он включён для совместимости со старыми приложениями.
Можно попробывать ещё его отключить ) О результатах напишу, но дело в том, что могут порушиться старые планы запросов.
И ещё, данная ошибка вроде как только для 64-битных систем.
Но у нас стоит сервер FreeBSD 32-бит с PAE, получается, что и в такой конфигурации эта ошибка может быть. Говорю по факту )
Отредактированно usershift (17.03.2011 01:06:05)
Неактивен
А, да, выход с MyISAM оказался очень временным, потому что сразу пошли локи )
Неактивен
paulus написал:
Какая неприятная штука Но выглядит и правда как ошибка. Попробуйте хотя
бы 5.1 + innodb_plugin. Хотя, можно и 5.5 сразу.
И сразу вопрос ещё, стоит для mysql
Client API version 5.0.92
он совместим с mysql 5.1 или даже 5.5? Какие могут быть проблемы при переходе на эти версии?
Неактивен
Клиентский протокол не меняется очень-очень давно. Единственное существенное
изменение было в 4.1, когда добавили более длинные хэши для паролей. Соответст-
венно, никаких проблем быть не должно.
Раз уж сказали слово FreeBSD — не могу не упомянуть: у них в портах MySQL соби-
рается как-то очень странно. Если есть возможность собрать из нормальных исходни-
ков, стоит это сделать. Часто ошибки InnoDB при этом исчезают сами собой. Ну и
о 64 битах всё равно стоит подумать
Да, и в любом случае с 5.0.9 стоит апгрейдиться, т.к. внутри ветки 5.0 версии меньше
30 — чрезвычайно нестабильные (первая более-менее стабильная была 32я, кажется,
а с 45 начиная они уже пошли хорошие).
UPD: Подумал, что, наверное, в первом посте опечатка, т.к. клиентская версия 92я
Неактивен
paulus написал:
UPD: Подумал, что, наверное, в первом посте опечатка, т.к. клиентская версия 92я
Да, опечатку исправил.
MySQL 5.0.92-log )
Отредактированно usershift (17.03.2011 02:37:16)
Неактивен
innodb_use_legacy_cardinality_alghoritm OFF ощутимого эффекта не дал. То есть никакого эффекта не дал.
Неактивен
Я бы начал с обновления MySQL. 5.5 может быть страшно, но 5.1 уже стабилен
несколько лет как.
Неактивен
Таже проблема что и у автора, версия mysql 5.5.15 на винде. Может кто нашел решение?
Неактивен