Почему мощность индекса в MySQL остается неизменной, когда я добавляю новый индекс?

Я добавил индекс FULLTEXT в одну из таблиц базы данных MySQL следующим образом:

ALTER TABLE members ADD FULLTEXT(about,fname,lname,job_title);

Проблема в том, что с помощью phpmyadmin я вижу, что кардинальность моего нового индекса составляет всего 1. Означает ли это, что индекс никогда не будет использоваться?

Я запустил команду анализа таблицы, но, похоже, она ничего не сделала.

analyze table members

Соответствующие типы полей индекса: varchar (100), varchar (100), text, varchar (200), а используемый механизм — MyISAM, а таблица содержит около 30 000 строк, все уникальные. Моя версия MySQL 5.0.45.

Я делаю что-то неправильно?


person Community    schedule 16.04.2009    source источник


Ответы (2)


Если у вас есть только 1 строка в таблице, количество элементов для индекса, конечно, должно быть 1. Он просто подсчитывает количество уникальных значений.

Если вы думаете об индексе как о таблице поиска, основанной на сегментах (например, хэше), то кардинальность — это количество сегментов.

Вот как это работает: когда вы строите индекс по набору столбцов (a,b,c,d), база данных просматривает все строки в таблице, просматривая упорядоченные четверки этих 4 столбцов для каждой строки. Допустим, ваша таблица выглядит так:

a  b  c  d  e   
-- -- -- -- --  
1  1  1  1  200 
1  1  1  1  300
1  2  1  1  200
1  3  1  1  200

Итак, база данных смотрит только на 4 столбца (a, b, c, d):

a  b  c  d  
-- -- -- --
1  1  1  1 
1  2  1  1 
1  3  1  1 

Видите, что осталось только 3 уникальных строки? Они станут нашими ведрами, но мы вернемся к этому. На самом деле для каждой строки в таблице также есть идентификатор записи или идентификатор строки. Итак, наша исходная таблица выглядит так:

(row id) a  b  c  d  e   
-------- -- -- -- -- --  
00000001 1  1  1  1  200 
00000002 1  1  1  1  300
00000003 1  2  1  1  200
00000004 1  3  1  1  200

Поэтому, когда мы смотрим только на 4 столбца (a,b,c,d), мы действительно смотрим также на идентификатор строки:

(row id) a  b  c  d 
-------- -- -- -- --
00000001 1  1  1  1
00000002 1  1  1  1
00000003 1  2  1  1
00000004 1  3  1  1

Но мы хотим выполнять поиск по (a,b,c,d), а не по идентификатору строки, поэтому мы получаем что-то вроде этого:

(a,b,c,d) (row id)
--------- --------
1,1,1,1   00000001
1,1,1,1   00000002
1,2,1,1   00000003
1,3,1,1   00000004

И, наконец, мы группируем вместе все идентификаторы строк, которые имеют одинаковые значения (a,b,c,d):

(a,b,c,d) (row id)
--------- ---------------------
1,1,1,1   00000001 and 00000002
1,2,1,1   00000003
1,3,1,1   00000004

Видеть, что? Значения (a,b,c,d), которые равны (1,1,1,1) (1,2,1,1) и (1,3,1,1), стали ключами для нашей таблицы поиска. в строки исходной таблицы.

На самом деле ничего из этого не происходит, но это должно дать вам хорошее представление о том, как можно реализовать "наивную" (то есть прямолинейную) реализацию индекса.

Но суть в следующем: кардинальность просто измеряет количество уникальных строк в индексе. В нашем примере это было количество ключей в нашей таблице поиска, равное 3.

Надеюсь, это поможет!

person Community    schedule 16.04.2009
comment
Спасибо за информацию об индексе. Очень хорошо объяснил. Мощность моего индекса должна быть больше 1, учитывая, что есть 30000 строк и почти у каждого члена есть другое имя? - person Tom; 16.04.2009
comment
Спасибо за объяснение об индексах, это было очень приятно, но ваше объяснение не ответило на заданный выше вопрос. - person Deepak Yadav; 17.07.2010
comment
Вы правы, я не сказал окончательный вывод явно: я просто показал, что 4 строки попадают в 3 корзины. Я уверен, что вы могли бы придумать еще одну строку, которую можно было бы добавить, которая попала бы в один из существующих 3 сегментов индекса. Это оставило бы количество сегментов без изменений, что также означало бы, что кардинальность индекса не изменилась. Извини за это. - person Shalom Craimer; 22.07.2010
comment
Хорошее объяснение. Но 'На самом деле ничего из этого на самом деле не происходит'!? Так что же происходит на самом деле...? Я чувствую себя немного смущенным. - person Paul Lo; 26.09.2014
comment
@PaulLo Ну, механизм базы данных, реализованный наивным образом, может выполнять все подробные шаги. Но я ожидаю, что большинство реализаций делают это по-другому — более эффективно используют ОЗУ и дисковые ресурсы, чтобы обеспечить меньшую задержку. - person Shalom Craimer; 27.09.2014

Я не могу однозначно ответить, почему MySQL не вычисляет кардинальность, но могу предположить. В руководстве по MySQL говорится:

Кардинальность: оценка количества уникальных значений в индексе. Это обновляется запуском ANALYZE TABLE или myisamchk -a. Количество элементов рассчитывается на основе статистики, хранящейся в виде целых чисел, поэтому значение не обязательно является точным даже для небольших таблиц. Чем выше кардинальность, тем выше вероятность того, что MySQL использует индекс при выполнении соединений.

Полнотекстовые индексы используются только в запросах MATCH ... AGAINST (...), что приводит к принудительному использованию индекса. Синтаксис MATCH ... AGAINST не работает, если для этих полей нет FULLTEXT индекса.

Я предполагаю, что количество элементов не вычисляется, потому что в этом нет необходимости.

Обратите внимание, что поиск по индексу работает, даже если кардинальность не установлена.

Для справки, оператор ANALYZE TABLE foobar, по-видимому, правильно устанавливает количество элементов.

person Community    schedule 16.04.2009