Кто-нибудь когда-нибудь успешно делал слияние индекса для MySQL? - PullRequest
4 голосов
/ 25 марта 2010

Установка:

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 ]

4 голосов
/ 25 марта 2010

Я понятия не имею, является ли это фактической причиной, но я думаю, что любая СУБД, достойная ее соли, увидит свойство "columns = 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, и, действительно, можетв общем случае: -)

2 голосов
/ 05 апреля 2010

Длинная спина:

Показывать индексы от Lesssong;

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

объясните, выберите * из песни меньше, где 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)

объяснение выбора * из t, где a = 1 или b = 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'
0 голосов
/ 07 апреля 2010

Жаль, что нет способа заставить MySQL использовать слияние, например, как заставить его использовать определенный индекс, когда он выбирает неправильный по умолчанию (случается редко, но я видел это и должен был разобраться с этим).

Полагаю, это просто потому, что вашим данным не хватает мощности для MySQL, чтобы решить, что стоит потратить время на использование индекса, не говоря уже о index_merge. 1800 строк - ничто - правда. Создайте не менее миллиона строк и сделайте каждую из них уникальной. Тогда он, вероятно, будет делать то, что вы хотите. С такой маленькой таблицей индекс ничего не делает для вас.

...