Кто-нибудь когда-нибудь успешно делал слияние индекса для MySQL?
Настроить:
mysql> create table t(a integer unsigned,b integer unsigned);
mysql> insert into t(a,b) values (1,2),(1,3),(2,4);
mysql> create index i_t_a on t(a);
mysql> create index i_t_b on t(b);
mysql> explain select * from t where a=1 or b=4;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | t | ALL | i_t_a,i_t_b | NULL | NULL | NULL | 3 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
Я что-то упускаю?
Обновить
mysql> explain select * from t where a=1 or b=4;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | t | ALL | i_t_a,i_t_b | NULL | NULL | NULL | 1863 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
Версия:
mysql> select version();
+----------------------+
| version() |
+----------------------+
| 5.1.36-community-log |
+----------------------+
Кто-нибудь когда-нибудь успешно делал слияние индекса для MySQL?
Я буду рад видеть успешные истории здесь:)
3 ответа
Длинная спина:
показывать индексы с урока;
Table, Non_unique, Key_name, Seq_in_index, Column_name, Collation, Cardinality, Sub_part, Packed, Null, Index_type, Comment
'lesssong', 0, 'PRIMARY', 1, 'S_ID', 'A', 50000, , '', '', 'BTREE', ''
'lesssong', 1, 'idx_s_name', 1, 'S_NAME', 'A', 25000, 10, '', '', 'BTREE', ''
'lesssong', 1, 'idx_S_ARID', 1, 'S_ARID', 'A', 1315, , '', '', 'BTREE', ''
'lesssong', 1, 'idxFTS', 1, 'S_NAME', '', 1, , '', '', 'FULLTEXT', ''
Количество = 50000
объясните, выберите * fromsongsong, где s_name='kv' или s_arid=4
1, 'SIMPLE', 'lesssong', 'index_merge', 'idx_s_name,idx_S_ARID,idxFTS', 'idx_s_name,idx_S_ARID', '12,4', '', 2, 'Using sort_union(idx_s_name,idx_S_ARID); Using where'
Состав:
'S_ID', 'int(10) unsigned', 'NO', 'PRI', '', 'auto_increment'
'S_ALID', 'int(10) unsigned', 'NO', '', '', ''
'S_ARID', 'int(10) unsigned', 'NO', 'MUL', '', ''
'S_NAME', 'varchar(100)', 'NO', 'MUL', '', ''
'S_LYRIC', 'text', 'NO', '', '', ''
'S_WRITER', 'varchar(45)', 'NO', '', '', ''
'S_LINK', 'varchar(255)', 'NO', '', '', ''
Даже для вас, структура, у меня это работает:
Я добавил случайные 100 значений:
insert into t(a,b) select ceil(rand()*5),ceil(rand()*30)
объяснить выбрать * из т, где а =1 или б =4;
id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
1, 'SIMPLE', 't', 'index_merge', 'i_t_a,i_t_b', 'i_t_a,i_t_b', '5,5', '', 32, 'Using union(i_t_a,i_t_b); Using where'
Я понятия не имею, является ли это фактической причиной, но я думаю, что любая СУБД, достойная ее соли, увидит свойство "rows=3" и просто решит, что не стоит даже смотреть на индексы. Скорость, с которой вы можете выполнить полное сканирование таблицы в трех строках, сделает любой другой метод спорным.
Попробуйте сделать то же самое с несколькими тысячами строк и посмотрите, получите ли вы те же результаты.
Отсюда комментатор заявляет, что "таблица, с которой я тестировал, привела к тому, что версия index-merge-union не использовала индексы в определенных ситуациях", хотя, похоже, они точно не знают, что это за ситуации:-) Вы можете поднять с группами поддержки MySQL (и разработчиков), а также.
Просто из интереса, что следующий запрос дает вам от EXPLAIN:
select * from t where a=1
union
select * from t where b=4;
И может быть, MySQL оценивает, использовать ли индексное объединение на основе данных в самой таблице. Если есть только 2 варианта a
и 3 варианта b
, он может снова решить, что ваш запрос в любом случае вернет большую часть строк, так что не стоит беспокоиться об оптимизации.
Вы можете попробовать как с большим количеством строк, так и с большим разнообразием значений в обоих a
а также b
колонны.
Имейте в виду, что это не основано на моих знаниях MySQL, я никогда не видел кодовую базу и не использовал продукт. Тем не менее, я проделал небольшую работу над определенным основным продуктом баз данных - так что этот совет основан на том, как я понимаю, чтобы делать вещи эффективно, что может быть не совсем так для MySQL, и, возможно, вообще не так вообще:-)
Жаль, что нет способа заставить MySQL использовать слияние, например, как заставить его использовать определенный индекс, когда он выбирает неправильный по умолчанию (случается редко, но я видел это и должен был с этим справиться),
Я предполагаю, что это просто потому, что у ваших данных недостаточно мощности для MySQL, чтобы решить, что стоит потратить время на использование индекса, не говоря уже о index_merge. 1800 строк - это ничего - правда. Создайте не менее миллиона строк и сделайте каждую из них уникальной. Тогда он, вероятно, будет делать то, что вы хотите. С такой маленькой таблицей индекс ничего не делает для вас.