Кто-нибудь когда-нибудь успешно делал слияние индекса для 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 строк - это ничего - правда. Создайте не менее миллиона строк и сделайте каждую из них уникальной. Тогда он, вероятно, будет делать то, что вы хотите. С такой маленькой таблицей индекс ничего не делает для вас.

Другие вопросы по тегам