Статьи

InnoDB Полнотекстовый поиск в MySQL 5.6 (часть 1)

Это сообщение написано Эрни Сухрада из MySQL Performance Blog.

Я никогда не был большим поклонником MyISAM; Я бы сказал, что в большинстве ситуаций любые возможные преимущества использования MyISAM значительно перевешиваются потенциальными недостатками и преимуществами InnoDB. Однако до MySQL 5.6 MyISAM был единственным механизмом хранения с поддержкой полнотекстового поиска (FTS). И я сталкивался со многими клиентами, для которых разумным шагом был бы переход на InnoDB, но из-за использования MyISAM FTS идея полной или частичной миграции по тем или иным причинам была непрактичным решением. Итак, когда впервые было объявлено о FTS для InnoDB, я подумал, что это может стать волшебной пулей, которая поможет таким клиентам реализовать все преимущества, которые были внедрены в InnoDB за последние несколько лет, и при этом сохранить свои возможности FTS без необходимость каких-либо значительных изменений кода.

К сожалению, я думаю, что надежда может быть преждевременной. Хотя верно, что InnoDB FTS в MySQL 5.6 синтаксически идентичен MyISAM FTS, в том смысле, что SQL, необходимый для запуска MATCH. AGAINST, является тем же самым (по модулю любые новые функции, представленные в InnoDB FTS), во многом это сходство конец.

ПРИМЕЧАНИЕ 1: Первоначально я планировал охватить все, что хотел обсудить в отношении InnoDB FTS, в этом посте, но я думаю, что здесь есть много интересного, поэтому вместо этого я разобью его на три части. Первая часть (эта) будет очень кратким обзором FTS в InnoDB и некоторыми наблюдениями, которые я сделал во время его настройки. Во второй части будут сравниваться результаты запросов между MyISAM FTS и InnoDB FTS по одним и тем же наборам данных, а затем, наконец, в третьей части мы рассмотрим производительность запросов . В случае, если новая версия 5.6 появится между этой частью и частью 3, я также вернусь к некоторым «причудам» из частей 1 и 2, чтобы увидеть, изменилось ли поведение.

ПРИМЕЧАНИЕ 2: Для целей этого обсуждения я использовал два отдельных набора данных. Первый — это набор из примерно 8 тысяч веб-страниц с очень SEO-наполнением, где заголовок документа — это заголовок страницы, а тело документа — тело страницы, лишенное тегов HTML. Мы назовем этот набор данных «SEO» — это около 20 МБ фактических данных. Другой представляет собой набор из примерно 790 тыс. Записей каталога, каждая из которых содержит имя, адрес и некоторую другую информацию общедоступных записей о каждом человеке. Мы назовем этот набор данных «DIR», и он составляет около 155 МБ фактических данных.

ПРИМЕЧАНИЕ 3. Кроме того, имейте в виду, что я использовал сообщества выпусков MySQL 5.5.30 и MySQL 5.6.10 без каких-либо настроек (с одним исключением, которое я объясню ниже) — идея этого исследования не состояла в том, чтобы найти Узнайте, как сделать InnoDB FTS невероятно быстрым, но просто понять, как он работает по сравнению с традиционными MyISAM FTS. Мы перейдем к производительности в третьем выпуске. На данный момент важно отметить, что буферный пул InnoDB для моего экземпляра 5.6 составляет 128 МБ, что меньше размера моих данных DIR.

Итак, со всем этим, давайте перейдем к этому.

Вот наше базовое определение таблицы для набора данных DIR. Таблица для набора данных SEO выглядит идентично, за исключением того, что мы заменим «полное_имя» на «заголовок» VARCHAR (255) и «подробности» на «тело» ТЕКСТА.

CREATE TABLE `dir_test_innodb` (
  `id` int(10) unsigned NOT NULL,
  `full_name` varchar(100) DEFAULT NULL,
  `details` text,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `full_name` (`full_name`,`details`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

У нас также есть идентичные таблицы, созданные в 5.5.30, где, разумеется, единственное отличие состоит в том, что движком является MyISAM, а не InnoDB. Загрузка данных осуществлялась с помощью простого Perl-скрипта, вставляя по одной строке за раз с включенным AutoCommit — помните, что фокус здесь пока не на производительности.

Загрузив данные, первое, что мы заметили, это то, что в нашей базе данных есть много «новых» файлов табличного пространства InnoDB:

-rw-rw----. 1 mysql mysql      8632 Feb 20 15:54 dir_test_innodb.frm
-rw-rw----. 1 mysql mysql 213909504 Feb 20 15:55 dir_test_innodb.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 16:09 FTS_00000000000000ad_0000000000000153_DOC_ID.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 16:09 FTS_00000000000000ad_ADDED.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 16:09 FTS_00000000000000ad_BEING_DELETED_CACHE.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 16:09 FTS_00000000000000ad_BEING_DELETED.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 16:09 FTS_00000000000000ad_CONFIG.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 16:09 FTS_00000000000000ad_DELETED_CACHE.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 16:09 FTS_00000000000000ad_DELETED.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 16:09 FTS_00000000000000ad_STOPWORDS.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 15:54 FTS_0000000000000114_0000000000000144_DOC_ID.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 15:54 FTS_0000000000000114_ADDED.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 15:54 FTS_0000000000000114_BEING_DELETED_CACHE.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 15:55 FTS_0000000000000114_BEING_DELETED.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 15:55 FTS_0000000000000114_CONFIG.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 15:54 FTS_0000000000000114_DELETED_CACHE.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 15:55 FTS_0000000000000114_DELETED.ibd
-rw-rw----. 1 mysql mysql     98304 Feb 20 15:54 FTS_0000000000000114_STOPWORDS.ibd
-rw-rw----. 1 mysql mysql      8618 Feb 20 16:09 seo_test_innodb.frm
-rw-rw----. 1 mysql mysql  37748736 Feb 20 16:29 seo_test_innodb.ibd

Для сравнения, вот что мы видим на стороне MyISAM:

-rw-rw----. 1 mysql mysql      8632 Feb 19 17:17 dir_test_myisam.frm
-rw-rw----. 1 mysql mysql 155011048 Feb 19 17:17 dir_test_myisam.MYD
-rw-rw----. 1 mysql mysql 153956352 Feb 19 17:18 dir_test_myisam.MYI
-rw-rw----. 1 mysql mysql      8618 Feb 20 16:11 seo_test_myisam.frm
-rw-rw----. 1 mysql mysql  21561096 Feb 20 16:11 seo_test_myisam.MYD
-rw-rw----. 1 mysql mysql  14766080 Feb 20 16:11 seo_test_myisam.MYI

Я также заметил, что если я просто загружаю данные в таблицу InnoDB, в которой никогда не было полнотекстового индекса, а затем создаю ее, генерируется следующее предупреждение:

mysql> alter table dir_test_innodb ADD FULLTEXT KEY (full_name, details);
Query OK, 0 rows affected, 1 warning (39.73 sec)
Records: 0  Duplicates: 0  Warnings: 1

mysql> show warnings;
+---------+------+--------------------------------------------------+
| Level   | Code | Message                                          |
+---------+------+--------------------------------------------------+
| Warning |  124 | InnoDB rebuilding table to add column FTS_DOC_ID |
+---------+------+--------------------------------------------------+

InnoDB Полнотекстовый поиск в MySQL 5.6 (часть 1)

Я никогда не был большим поклонником MyISAM; Я бы сказал, что в большинстве ситуаций любые возможные преимущества использования MyISAM значительно перевешиваются потенциальными недостатками и преимуществами InnoDB. Однако до MySQL 5.6 MyISAM был единственным механизмом хранения с поддержкой полнотекстового поиска (FTS). И я сталкивался со многими клиентами, для которых разумным шагом был бы переход на InnoDB, но из-за использования MyISAM FTS идея полной или частичной миграции по тем или иным причинам была непрактичным решением. Итак, когда впервые было объявлено о FTS для InnoDB, я подумал, что это может стать волшебной пулей, которая поможет таким клиентам реализовать все преимущества, которые были внедрены в InnoDB за последние несколько лет, и при этом сохранить свои возможности FTS без необходимость каких-либо значительных изменений кода.

К сожалению, я думаю, что надежда может быть преждевременной. Хотя верно, что InnoDB FTS в MySQL 5.6 синтаксически идентичен MyISAM FTS, в том смысле, что SQL, необходимый для запуска MATCH. AGAINST, является тем же самым (по модулю любые новые функции, представленные в InnoDB FTS), во многом это сходство конец.

ПРИМЕЧАНИЕ 1: Первоначально я планировал охватить все, что хотел обсудить в отношении InnoDB FTS, в этом посте, но я думаю, что здесь есть много интересного, поэтому вместо этого я разобью его на три части. Первая часть (эта) будет очень кратким обзором FTS в InnoDB и некоторыми наблюдениями, которые я сделал во время его настройки. Во второй части будут сравниваться результаты запросов между MyISAM FTS и InnoDB FTS по одним и тем же наборам данных, а затем, наконец, в третьей части мы рассмотрим производительность запросов . В случае, если новая версия 5.6 появится между этой частью и частью 3, я также вернусь к некоторым «причудам» из частей 1 и 2, чтобы увидеть, изменилось ли поведение.

ПРИМЕЧАНИЕ 2: Для целей этого обсуждения я использовал два отдельных набора данных. Первый — это набор из примерно 8 тысяч веб-страниц с очень SEO-наполнением, где заголовок документа — это заголовок страницы, а тело документа — тело страницы, лишенное тегов HTML. Мы назовем этот набор данных «SEO» — это около 20 МБ фактических данных. Другой представляет собой набор из примерно 790 тыс. Записей каталога, каждая из которых содержит имя, адрес и некоторую другую информацию общедоступных записей о каждом человеке. Мы назовем этот набор данных «DIR», и он составляет около 155 МБ фактических данных.

ПРИМЕЧАНИЕ 3. Кроме того, имейте в виду, что я использовал сообщества выпусков MySQL 5.5.30 и MySQL 5.6.10 без каких-либо настроек (с одним исключением, которое я объясню ниже) — идея этого исследования не состояла в том, чтобы найти Узнайте, как сделать InnoDB FTS невероятно быстрым, но просто понять, как он работает по сравнению с традиционными MyISAM FTS. Мы перейдем к производительности в третьем выпуске. На данный момент важно отметить, что буферный пул InnoDB для моего экземпляра 5.6 составляет 128 МБ, что меньше размера моих данных DIR.

Итак, со всем этим, давайте перейдем к этому.

Вот наше базовое определение таблицы для набора данных DIR. Таблица для набора данных SEO выглядит идентично, за исключением того, что мы заменим «полное_имя» на «заголовок» VARCHAR (255) и «подробности» на «тело» ТЕКСТА.


Оболочка

CREATE TABLE `dir_test_innodb` (` id` int (10) без знака NOT NULL, `full_name` varchar (100) DEFAULT NULL, текст` details`, ПЕРВИЧНЫЙ КЛЮЧ (`id`), КЛЮЧ FULLTEXT` full_name` (`full_name` (` full_name`), ` `details`)) ENGINE = InnoDB CHARSET ПО УМОЛЧАНИЮ = utf8

1

2

3

4

5

6

7

CREATE TABLE`dir_test_innodb` (

`Id`int (10) unsignedNOTNULL,

`Full_name`varchar (100) DEFAULTNULL,

`Details`text,

ПЕРВИЧНЫЙ КЛЮЧ (`id`),

FULLTEXT KEY `полное имя` (` полное_имя`, `подробности`)

) ENGINE = InnoDB DEFAULTCHARSET = utf8

У нас также есть идентичные таблицы, созданные в 5.5.30, где, разумеется, единственное отличие состоит в том, что движком является MyISAM, а не InnoDB. Загрузка данных осуществлялась с помощью простого Perl-скрипта, вставляя по одной строке за раз с включенным AutoCommit — помните, что фокус здесь пока не на производительности.

Загрузив данные, первое, что мы заметили, это то, что в нашей базе данных есть много «новых» файлов табличного пространства InnoDB:


Оболочка

-rw-RW —-. 1 mysql mysql 8632 20 февраля 15:54 dir_test_innodb.frm -rw-rw —-. 1 mysql mysql 213909504 20 февраля 15:55 dir_test_innodb.ibd -rw-rw —-. 1 mysql mysql 98304 20 фев. 16:09 FTS_00000000000000ad_0000000000000153_DOC_ID.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 16:09 FTS_00000000000000ad_ADDED.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 16:09 FTS_00000000000000ad_BEING_DELETED_CACHE.ibd -rw-rw —-. 1 mysql mysql 98304 20 фев. 16:09 FTS_00000000000000ad_BEING_DELETED.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 16:09 FTS_00000000000000ad_CONFIG.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 16:09 FTS_00000000000000ad_DELETED_CACHE.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 16:09 FTS_00000000000000ad_DELETED.ibd -rw-rw —-. 1 mysql mysql 98304 20 фев. 16:09 FTS_00000000000000ad_STOPWORDS.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:54 FTS_0000000000000114_0000000000000144_DOC_ID.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:54 FTS_0000000000000114_ADDED.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:54 FTS_0000000000000114_BEING_DELETED_CACHE.ibd -rw-rw —-. 1 mysql mysql 98304 20.02.15 15:55 FTS_0000000000000114_BEING_DELETED.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:55 FTS_0000000000000114_CONFIG.ibd -rw-rw —-. 1 mysql mysql 98304 20 февр. 15:54 FTS_0000000000000114_DELETED_CACHE.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:55 FTS_0000000000000114_DELETED.ibd -rw-rw —-. 1 mysql mysql 98304 20 февр. 15:54 FTS_0000000000000114_STOPWORDS.ibd -rw-rw —-. 1 mysql mysql 8618 20 февраля 16:09 seo_test_innodb.frm -rw-rw —-. 1 mysql mysql 37748736 20 февраля 16:29 seo_test_innodb.ibdibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:54 FTS_0000000000000114_BEING_DELETED_CACHE.ibd -rw-rw —-. 1 mysql mysql 98304 20.02.15 15:55 FTS_0000000000000114_BEING_DELETED.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:55 FTS_0000000000000114_CONFIG.ibd -rw-rw —-. 1 mysql mysql 98304 20 февр. 15:54 FTS_0000000000000114_DELETED_CACHE.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:55 FTS_0000000000000114_DELETED.ibd -rw-rw —-. 1 mysql mysql 98304 20 февр. 15:54 FTS_0000000000000114_STOPWORDS.ibd -rw-rw —-. 1 mysql mysql 8618 20 февраля 16:09 seo_test_innodb.frm -rw-rw —-. 1 mysql mysql 37748736 20 февраля 16:29 seo_test_innodb.ibdibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:54 FTS_0000000000000114_BEING_DELETED_CACHE.ibd -rw-rw —-. 1 mysql mysql 98304 20.02.15 15:55 FTS_0000000000000114_BEING_DELETED.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:55 FTS_0000000000000114_CONFIG.ibd -rw-rw —-. 1 mysql mysql 98304 20 февр. 15:54 FTS_0000000000000114_DELETED_CACHE.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:55 FTS_0000000000000114_DELETED.ibd -rw-rw —-. 1 mysql mysql 98304 20 февр. 15:54 FTS_0000000000000114_STOPWORDS.ibd -rw-rw —-. 1 mysql mysql 8618 20 февраля 16:09 seo_test_innodb.frm -rw-rw —-. 1 mysql mysql 37748736 20 февраля 16:29 seo_test_innodb.ibd55 FTS_0000000000000114_CONFIG.ibd -rw-rw —-. 1 mysql mysql 98304 20 февр. 15:54 FTS_0000000000000114_DELETED_CACHE.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:55 FTS_0000000000000114_DELETED.ibd -rw-rw —-. 1 mysql mysql 98304 20 февр. 15:54 FTS_0000000000000114_STOPWORDS.ibd -rw-rw —-. 1 mysql mysql 8618 20 февраля 16:09 seo_test_innodb.frm -rw-rw —-. 1 mysql mysql 37748736 20 февраля 16:29 seo_test_innodb.ibd55 FTS_0000000000000114_CONFIG.ibd -rw-rw —-. 1 mysql mysql 98304 20 февр. 15:54 FTS_0000000000000114_DELETED_CACHE.ibd -rw-rw —-. 1 mysql mysql 98304 20 февраля 15:55 FTS_0000000000000114_DELETED.ibd -rw-rw —-. 1 mysql mysql 98304 20 февр. 15:54 FTS_0000000000000114_STOPWORDS.ibd -rw-rw —-. 1 mysql mysql 8618 20 февраля 16:09 seo_test_innodb.frm -rw-rw —-. 1 mysql mysql 37748736 20 февраля 16:29 seo_test_innodb.ibd

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

-rw-rw —-. 1mysql mysql8632Feb2015: 54dir_test_innodb.frm

-rw-rw —-. 1mysql mysql213909504Feb2015: 55dir_test_innodb.ibd

-rw-rw —-. 1mysql mysql 98304Feb2016: 09FTS_00000000000000ad_0000000000000153_DOC_ID.ibd

-rw-rw —-. 1mysql mysql 98304Feb2016: 09FTS_00000000000000ad_ADDED.ibd

-rw-rw —-. 1mysql mysql 98304Feb2016: 09FTS_00000000000000ad_BEING_DELETED_CACHE.ibd

-rw-rw —-. 1mysql mysql 98304Feb2016: 09FTS_00000000000000ad_BEING_DELETED.ibd

-rw-rw —-. 1mysql mysql 98304Feb2016: 09FTS_00000000000000ad_CONFIG.ibd

-rw-rw —-. 1mysql mysql 98304Feb2016: 09FTS_00000000000000ad_DELETED_CACHE.ibd

-rw-rw —-. 1mysql mysql 98304Feb2016: 09FTS_00000000000000ad_DELETED.ibd

-rw-rw —-. 1mysql mysql 98304Feb2016: 09FTS_00000000000000ad_STOPWORDS.ibd

-rw-rw —-. 1mysql mysql 98304Feb2015: 54FTS_0000000000000114_0000000000000144_DOC_ID.ibd

-rw-rw —-. 1mysql mysql 98304Feb2015: 54FTS_0000000000000114_ADDED.ibd

-rw-rw —-. 1mysql mysql 98304Feb2015: 54FTS_0000000000000114_BEING_DELETED_CACHE.ibd

-rw-rw —-. 1mysql mysql 98304Feb2015: 55FTS_0000000000000114_BEING_DELETED.ibd

-rw-rw —-. 1mysql mysql 98304Feb2015: 55FTS_0000000000000114_CONFIG.ibd

-rw-rw —-. 1mysql mysql 98304Feb2015: 54FTS_0000000000000114_DELETED_CACHE.ibd

-rw-rw —-. 1mysql mysql 98304Feb2015: 55FTS_0000000000000114_DELETED.ibd

-rw-rw —-. 1mysql mysql 98304Feb2015: 54FTS_0000000000000114_STOPWORDS.ibd

-rw-rw —-. 1mysql mysql8618Feb2016: 09seo_test_innodb.frm

-rw-rw —-. 1mysql mysql37748736Feb2016: 29seo_test_innodb.ibd

Для сравнения, вот что мы видим на стороне MyISAM:


Оболочка

-rw-RW —-.
1 mysql mysql 8632 19 февраля 17:17 dir_test_myisam.frm -rw-rw —-. 1 mysql mysql 155011048 19 февраля 17:17 dir_test_myisam.MYD -rw-rw —-. 1 mysql mysql 153956352 19 февраля 17:18 dir_test_myisam.MYI -rw-rw —-. 1 mysql mysql 8618 20 февраля 16:11 seo_test_myisam.frm -rw-rw —-. 1 mysql mysql 21561096 20 февраля 16:11 seo_test_myisam.MYD -rw-rw —-. 1 mysql mysql 14766080 20 февраля 16:11 seo_test_myisam.MYI

1

2

3

4

5

6

-rw-rw —-. 1mysql mysql8632Feb1917: 17dir_test_myisam.frm

-rw-rw —-. 1mysql mysql155011048Feb1917: 17dir_test_myisam.MYD

-rw-rw —-. 1mysql mysql153956352Feb1917: 18dir_test_myisam.MYI

-rw-rw —-. 1mysql mysql8618Feb2016: 11seo_test_myisam.frm

-rw-rw —-. 1mysql mysql21561096Feb2016: 11seo_test_myisam.MYD

-rw-rw —-. 1mysql mysql14766080Feb2016: 11seo_test_myisam.MYI

Я также заметил, что если я просто загружаю данные в таблицу InnoDB, в которой никогда не было полнотекстового индекса, а затем создаю ее, генерируется следующее предупреждение:


Оболочка

mysql> изменить таблицу dir_test_innodb ДОБАВИТЬ КЛЮЧ FULLTEXT (полное имя, подробности);
Запрос в порядке, затронуто 0 строк, 1 предупреждение (39,73 с). Записи: 0 Дубликаты: 0 Предупреждения: 1 mysql> Показать предупреждения; + ——— + —— + ——————————— —————— + | Уровень | Код | Сообщение | + ——— + —— + ——————————— —————— + | Предупреждение 124 | Перестройка таблицы InnoDB для добавления столбца FTS_DOC_ID | + ——— + —— + ——————————— —————— +

1

2

3

4

5

6

7

8

9

10

mysql> изменить таблицу dir_test_innodb ДОБАВИТЬ КЛЮЧ FULLTEXT (полное имя, подробности);

Запрос в порядке, 0 строк затронуто, 1 предупреждение (39,73 с)

Записи: 0Duplicates: 0Warnings: 1

mysql> показывать предупреждения;

+ ——— + —— + ——————————— —————— +

| Уровень | Код | Сообщение |

+ ——— + —— + ——————————— —————— +

| Предупреждение | 124 | InnoDB перестраивает столбец toadd таблицы FTS_DOC_ID |

+ ——— + —— + ——————————— —————— +

Это не имеет большого смысла для меня. Почему InnoDB нужно добавить скрытый столбец (аналогично GEN_CLUST_INDEX, если вы не определяете PRIMARY KEY, я полагаю), когда у меня уже есть INT UNSIGNED PK, которого должно быть достаточно для любого вида идентификатора документа? Как выясняется, если вы создадите столбец с именем FTS_DOC_ID, представляющий собой BIGINT UNSIGNED NOT NULL с уникальным индексом, таблицу не нужно перестраивать. Самый важный элемент, который следует здесь отметить, — FTS_DOC_ID должен быть прописан и указан именно таким образом — ВСЕ КОПИИ . Если вы попробуете «fts_doc_id» или любую другую комбинацию букв, вы получите ошибку:

mysql> CREATE TABLE dir_test_innodb4 (fts_doc_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
ERROR 1166 (42000): Incorrect column name 'fts_doc_id'

Various points in the documentation mention the notion of a “document ID” that “might reflect the value of an ID column that you defined for the underlying table, or it can be a sequence value generated by InnoDB when the table does not contain a suitable column,” but there are only a handful of references to FTS_DOC_ID found when searching the MySQL 5.6 manual, and the only page which appears to suggest how using an explicitly-defined column is done is this one, which discusses improving bulk insert performance. At the very bottom, the page claims that you can speed up bulk loading into an InnoDB FT index by declaring a column called FTS_DOC_ID at table creation time of type BIGINT UNSIGNED NOT NULL with a unique index on it, loading your data, and then creating the FT index after the data is loaded.

One obvious problem wih those instructions is that if you define a column and a unique key as they suggest, your data won’t load due to unique key constraint violations unless you also do something to provide some sort of sequence value for that column, whether as an auto_increment value or via some other means, but the bit that troubles me further is the introduction of a column-level case-sensitivity requirement that only seems to actually matter at table creation time. Once I’ve got a table with an explicit FTS_DOC_ID column, however, MySQL apparently has no problem with either of the following statements:

mysql> insert into dir_test_innodb3 (fts_doc_id, full_name) values (1, 'john smith');
mysql> select * from dir_test_innodb3 where fts_doc_id=1;

Philosophically, I find that kind of behavior unsettling. I don’t like case-sensitivity in my table or column names to begin with (I may be one of the few people that likes lower_case_table_names = 1 in /etc/my.cnf), but I think it’s even worse that the case-sensitivity only matters some of the time. That strikes me as a good recipe for DBA frustration.

Now, let’s return to all of those FTS_*.ibd files. What, exactly, are they? In short, the _CONFIG.ibd file contains configuration info about the FT index (the same sort of configuration data that can be queried out of the I_S.INNODB_FT_CONFIG table, as I’ll discuss momentarily), and the others contain document IDs of new rows that are added to or removed from the table and which need to be merged back into or removed from the main index. I’m not entirely sure about the _STOPWORDS.ibd file just yet; I thought it might be somehow related to a custom stopwords table, but that doesn’t seem to be the case (or at least not in the way that I had thought), so I will need to look through the source to figure out what’s going on there.

In any case, for each new FULLTEXT KEY that you create, you’ll get a corresponding FTS_*_DOC_ID.ibd file (but none of the others), and if you drop a FT index, the its corresponding FTS_*_DOC_ID.ibd file will also be removed. HOWEVER, even if you drop all of the FT indexes for a given table, you’re still left with all of the other FTS_*.ibd files, and it appears that the only way to get rid of them is to actually rebuild the table.

-rw-rw----. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_ADDED.ibd
-rw-rw----. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_BEING_DELETED_CACHE.ibd
-rw-rw----. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_BEING_DELETED.ibd
-rw-rw----. 1 mysql mysql 98304 Feb 20 19:07 FTS_0000000000000025_CONFIG.ibd
-rw-rw----. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_DELETED_CACHE.ibd
-rw-rw----. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_DELETED.ibd
-rw-rw----. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_STOPWORDS.ibd

InnoDB Full-text Search in MySQL 5.6 (part 1)

February 26, 2013 By
Ernie Souhrada
Leave a Comment

I’ve never been a very big fan of MyISAM; I would argue that in most situations, any possible advantages to using MyISAM are far outweighed by the potential disadvantages and the strengths of InnoDB. However, up until MySQL 5.6, MyISAM was the only storage engine with support for full-text search (FTS). And I’ve encountered many customers for whom the prudent move would be a migration to InnoDB, but due to their use of MyISAM FTS, the idea of a complete or partial migration was, for one reason or another, an impractical solution. So, when FTS for InnoDB was first announced, I thought this might end up being the magic bullet that would help these sorts of customers realize all of the benefits that have been engineered into InnoDB over the past few years and still keep their FTS capability without having to make any significant code changes.

Unfortunately, I think that hope may be premature. While it is true that InnoDB FTS in MySQL 5.6 is syntactically identical to MyISAM FTS, in the sense that the SQL required to run a MATCH .. AGAINST is the same (modulo any new features introduced with InnoDB FTS), that’s largely where the similarities end.

NOTE 1: I was originally planning to cover everything I wanted to discuss with respect to InnoDB FTS in this one post, but I think there’s a lot of interesting stuff here, so I will break it into three pieces instead. The first part (this one) will be a very quick overview of FTS in InnoDB and some observations that I’ve made while getting it configured. The second part will compare query results between MyISAM FTS and InnoDB FTS over the same data sets, and then finally in the third installment, we’ll look at query performance. In the event that a new release of 5.6 appears between now and part 3, I’ll also revisit some of the “quirks” from parts 1 and 2 to see if the behavior has changed.

NOTE 2: For purposes of this discussion, I used two separate data sets. The first one is a set of about 8K very SEO-stuffed web pages, wherein the document title is the page title, and the document body is the HTML-tag-stripped body of the page. We’ll call this data set “SEO” – it’s about 20MB of actual data. The other one is a set of about 790K directory records, each one containing the name, address, and some other public-records-type information about each person. We’ll call this data set “DIR”, and it’s about 155MB of actual data.

NOTE 3: Also, keep in mind that I used the community editions of MySQL 5.5.30 and MySQL 5.6.10 with no tuning whatsoever (with one exception that I’ll explain below) – the idea behind this investigation wasn’t to find out how to make InnoDB FTS blazingly-fast, but simply to get a sense of how it works compared to traditional MyISAM FTS. We’ll get to performance in the third installment. For now, the important number here is to note that the InnoDB buffer pool for my 5.6 instance is 128MB – smaller than the size of my DIR data.

So, with all of that out of the way, let’s get to it.

Here is our basic table definition for the DIR dataset. The table for the SEO dataset looks identical, except that we replace “full_name” with a VARCHAR(255) “title” and “details” with a TEXT “body”.

Shell
CREATE TABLE `dir_test_innodb` ( `id` int(10) unsigned NOT NULL, `full_name` varchar(100) DEFAULT NULL, `details` text, PRIMARY KEY (`id`), FULLTEXT KEY `full_name` (`full_name`,`details`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
1
2
3
4
5
6
7
CREATE TABLE`dir_test_innodb`(
`id`int(10)unsignedNOTNULL,
`full_name`varchar(100)DEFAULTNULL,
`details`text,
PRIMARY KEY(`id`),
FULLTEXT KEY`full_name`(`full_name`,`details`)
)ENGINE=InnoDB DEFAULTCHARSET=utf8

We also have identical tables created in 5.5.30 where, of course, the only difference is that the engine is MyISAM rather than InnoDB. Loading the data was done via a simple Perl script, inserting one row at a time with AutoCommit enabled – remember, the focus here isn’t on performance just yet.

Having loaded the data, the first thing we notice is that there are a lot of “new” InnoDB tablespace files in our database directory:

Shell
-rw-rw—-. 1 mysql mysql 8632 Feb 20 15:54 dir_test_innodb.frm -rw-rw—-. 1 mysql mysql 213909504 Feb 20 15:55 dir_test_innodb.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 16:09 FTS_00000000000000ad_0000000000000153_DOC_ID.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 16:09 FTS_00000000000000ad_ADDED.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 16:09 FTS_00000000000000ad_BEING_DELETED_CACHE.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 16:09 FTS_00000000000000ad_BEING_DELETED.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 16:09 FTS_00000000000000ad_CONFIG.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 16:09 FTS_00000000000000ad_DELETED_CACHE.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 16:09 FTS_00000000000000ad_DELETED.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 16:09 FTS_00000000000000ad_STOPWORDS.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 15:54 FTS_0000000000000114_0000000000000144_DOC_ID.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 15:54 FTS_0000000000000114_ADDED.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 15:54 FTS_0000000000000114_BEING_DELETED_CACHE.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 15:55 FTS_0000000000000114_BEING_DELETED.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 15:55 FTS_0000000000000114_CONFIG.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 15:54 FTS_0000000000000114_DELETED_CACHE.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 15:55 FTS_0000000000000114_DELETED.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 15:54 FTS_0000000000000114_STOPWORDS.ibd -rw-rw—-. 1 mysql mysql 8618 Feb 20 16:09 seo_test_innodb.frm -rw-rw—-. 1 mysql mysql 37748736 Feb 20 16:29 seo_test_innodb.ibd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-rw-rw—-.1mysql mysql8632Feb2015:54dir_test_innodb.frm
-rw-rw—-.1mysql mysql213909504Feb2015:55dir_test_innodb.ibd
-rw-rw—-.1mysql mysql  98304Feb2016:09FTS_00000000000000ad_0000000000000153_DOC_ID.ibd
-rw-rw—-.1mysql mysql  98304Feb2016:09FTS_00000000000000ad_ADDED.ibd
-rw-rw—-.1mysql mysql  98304Feb2016:09FTS_00000000000000ad_BEING_DELETED_CACHE.ibd
-rw-rw—-.1mysql mysql  98304Feb2016:09FTS_00000000000000ad_BEING_DELETED.ibd
-rw-rw—-.1mysql mysql  98304Feb2016:09FTS_00000000000000ad_CONFIG.ibd
-rw-rw—-.1mysql mysql  98304Feb2016:09FTS_00000000000000ad_DELETED_CACHE.ibd
-rw-rw—-.1mysql mysql  98304Feb2016:09FTS_00000000000000ad_DELETED.ibd
-rw-rw—-.1mysql mysql  98304Feb2016:09FTS_00000000000000ad_STOPWORDS.ibd
-rw-rw—-.1mysql mysql  98304Feb2015:54FTS_0000000000000114_0000000000000144_DOC_ID.ibd
-rw-rw—-.1mysql mysql  98304Feb2015:54FTS_0000000000000114_ADDED.ibd
-rw-rw—-.1mysql mysql  98304Feb2015:54FTS_0000000000000114_BEING_DELETED_CACHE.ibd
-rw-rw—-.1mysql mysql  98304Feb2015:55FTS_0000000000000114_BEING_DELETED.ibd
-rw-rw—-.1mysql mysql  98304Feb2015:55FTS_0000000000000114_CONFIG.ibd
-rw-rw—-.1mysql mysql  98304Feb2015:54FTS_0000000000000114_DELETED_CACHE.ibd
-rw-rw—-.1mysql mysql  98304Feb2015:55FTS_0000000000000114_DELETED.ibd
-rw-rw—-.1mysql mysql  98304Feb2015:54FTS_0000000000000114_STOPWORDS.ibd
-rw-rw—-.1mysql mysql8618Feb2016:09seo_test_innodb.frm
-rw-rw—-.1mysql mysql37748736Feb2016:29seo_test_innodb.ibd

By comparison, this is what we see on the MyISAM side:

Shell
-rw-rw—-. 1 mysql mysql 8632 Feb 19 17:17 dir_test_myisam.frm -rw-rw—-. 1 mysql mysql 155011048 Feb 19 17:17 dir_test_myisam.MYD -rw-rw—-. 1 mysql mysql 153956352 Feb 19 17:18 dir_test_myisam.MYI -rw-rw—-. 1 mysql mysql 8618 Feb 20 16:11 seo_test_myisam.frm -rw-rw—-. 1 mysql mysql 21561096 Feb 20 16:11 seo_test_myisam.MYD -rw-rw—-. 1 mysql mysql 14766080 Feb 20 16:11 seo_test_myisam.MYI
1
2
3
4
5
6
-rw-rw—-.1mysql mysql8632Feb1917:17dir_test_myisam.frm
-rw-rw—-.1mysql mysql155011048Feb1917:17dir_test_myisam.MYD
-rw-rw—-.1mysql mysql153956352Feb1917:18dir_test_myisam.MYI
-rw-rw—-.1mysql mysql8618Feb2016:11seo_test_myisam.frm
-rw-rw—-.1mysql mysql21561096Feb2016:11seo_test_myisam.MYD
-rw-rw—-.1mysql mysql14766080Feb2016:11seo_test_myisam.MYI

I also observed that if I simply load the data into an InnoDB table that has never had a full-text index on it, and then I create one, the following warning is generated:

Shell
mysql> alter table dir_test_innodb ADD FULLTEXT KEY (full_name, details); Query OK, 0 rows affected, 1 warning (39.73 sec) Records: 0 Duplicates: 0 Warnings: 1 mysql> show warnings; +———+——+—————————————————+ | Level | Code | Message | +———+——+—————————————————+ | Warning | 124 | InnoDB rebuilding table to add column FTS_DOC_ID | +———+——+—————————————————+
1
2
3
4
5
6
7
8
9
10
mysql>alter table dir_test_innodb ADD FULLTEXT KEY(full_name,details);
Query OK,0rows affected,1warning(39.73sec)
Records:0Duplicates:0Warnings:1
mysql>show warnings;
+———+——+—————————————————+
|Level  |Code|Message|
+———+——+—————————————————+
|Warning|124|InnoDB rebuilding table toadd column FTS_DOC_ID|
+———+——+—————————————————+

This doesn’t make a lot of sense to me. Why does InnoDB need to add a hidden column (similar to GEN_CLUST_INDEX when you don’t define a PRIMARY KEY, I assume) when I already have an INT UNSIGNED PK that should suffice as any sort of document ID ? As it turns out, if you create a column called FTS_DOC_ID which is a BIGINT UNSIGNED NOT NULL with a unique index on it, your table doesn’t need to be rebuilt. The most important item to note here – FTS_DOC_ID must be spelled and specified exactly that way – IN ALL CAPS. If you try “fts_doc_id” or any other mixture of lettercase, you’ll get an error:

Shell
mysql> CREATE TABLE dir_test_innodb4 (fts_doc_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY); ERROR 1166 (42000): Incorrect column name ‘fts_doc_id’
1
2
mysql>CREATE TABLE dir_test_innodb4(fts_doc_id BIGINT UNSIGNEDNOTNULLAUTO_INCREMENT PRIMARY KEY);
ERROR1166(42000):Incorrect column name’fts_doc_id’

Various points in the documentation mention the notion of a “document ID” that “might reflect the value of an ID column that you defined for the underlying table, or it can be a sequence value generated by InnoDB when the table does not contain a suitable column,” but there are only a handful of references to FTS_DOC_ID found when searching the MySQL 5.6 manual, and the only page which appears to suggest how using an explicitly-defined column is done is this one, which discusses improving bulk insert performance. At the very bottom, the page claims that you can speed up bulk loading into an InnoDB FT index by declaring a column called FTS_DOC_ID at table creation time of type BIGINT UNSIGNED NOT NULL with a unique index on it, loading your data, and then creating the FT index after the data is loaded.

One obvious problem wih those instructions is that if you define a column and a unique key as they suggest, your data won’t load due to unique key constraint violations unless you also do something to provide some sort of sequence value for that column, whether as an auto_increment value or via some other means, but the bit that troubles me further is the introduction of a column-level case-sensitivity requirement that only seems to actually matter at table creation time. Once I’ve got a table with an explicit FTS_DOC_ID column, however, MySQL apparently has no problem with either of the following statements:

Shell
mysql> insert into dir_test_innodb3 (fts_doc_id, full_name) values (1, ‘john smith’); mysql> select * from dir_test_innodb3 where fts_doc_id=1;
1
2
mysql>insert into dir_test_innodb3(fts_doc_id,full_name)values(1,’john smith’);
mysql>select*from dir_test_innodb3 where fts_doc_id=1;

Philosophically, I find that kind of behavior unsettling. I don’t like case-sensitivity in my table or column names to begin with (I may be one of the few people that likes lower_case_table_names = 1 in /etc/my.cnf), but I think it’s even worse that the case-sensitivity only matters some of the time. That strikes me as a good recipe for DBA frustration.

Now, let’s return to all of those FTS_*.ibd files. What, exactly, are they? In short, the _CONFIG.ibd file contains configuration info about the FT index (the same sort of configuration data that can be queried out of the I_S.INNODB_FT_CONFIG table, as I’ll discuss momentarily), and the others contain document IDs of new rows that are added to or removed from the table and which need to be merged back into or removed from the main index. I’m not entirely sure about the _STOPWORDS.ibd file just yet; I thought it might be somehow related to a custom stopwords table, but that doesn’t seem to be the case (or at least not in the way that I had thought), so I will need to look through the source to figure out what’s going on there.

In any case, for each new FULLTEXT KEY that you create, you’ll get a corresponding FTS_*_DOC_ID.ibd file (but none of the others), and if you drop a FT index, the its corresponding FTS_*_DOC_ID.ibd file will also be removed. HOWEVER, even if you drop all of the FT indexes for a given table, you’re still left with all of the other FTS_*.ibd files, and it appears that the only way to get rid of them is to actually rebuild the table.

Shell
-rw-rw—-. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_ADDED.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_BEING_DELETED_CACHE.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_BEING_DELETED.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 19:07 FTS_0000000000000025_CONFIG.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_DELETED_CACHE.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_DELETED.ibd -rw-rw—-. 1 mysql mysql 98304 Feb 20 18:57 FTS_0000000000000025_STOPWORDS.ibd
1
2
3
4
5
6
7
-rw-rw—-.1mysql mysql98304Feb2018:57FTS_0000000000000025_ADDED.ibd
-rw-rw—-.1mysql mysql98304Feb2018:57FTS_0000000000000025_BEING_DELETED_CACHE.ibd
-rw-rw—-.1mysql mysql98304Feb2018:57FTS_0000000000000025_BEING_DELETED.ibd
-rw-rw—-.1mysql mysql98304Feb2019:07FTS_0000000000000025_CONFIG.ibd
-rw-rw—-.1mysql mysql98304Feb2018:57FTS_0000000000000025_DELETED_CACHE.ibd
-rw-rw—-.1mysql mysql98304Feb2018:57FTS_0000000000000025_DELETED.ibd
-rw-rw—-.1mysql mysql98304Feb2018:57FTS_0000000000000025_STOPWORDS.ibd

Also, while we’re on the subject of adding and dropping FT indexes, it’s entirely possible to DROP multiple FT indexes with InnoDB in the same ALTER TABLE statement, but it’s not possible to CREATE more than one at a time. If you try it, this is what happens:

mysql> alter table dir_test_innodb ADD FULLTEXT KEY (full_name, details), 
       ADD FULLTEXT KEY (details);
ERROR 1795 (HY000): InnoDB presently supports one FULLTEXT index creation at a time

That’s an odd limitation. Do it as two separate ALTER statements, and it appears to work fine.

But here’s where things start to get even weirder. According to the documentation, if we specify the name of a table that has a FT index for the global variable innodb_ft_aux_table, we should be able to get some statistics about the FT indexes on that table by querying the various I_S.INNODB_FT_* tables. In particular, the INNODB_FT_CONFIG table is supposed to “display metadata about the FULLTEXT index and associated processing for an InnoDB table.” The documentation also tells us that we can keep our FT indexes up to date by setting innodb_optimize_fulltext_only = 1 and then running OPTIMIZE TABLE, and that we might have to run OPTIMIZE TABLE multiple times if we’ve had a lot of changes to the table.

This all sounds pretty good, in theory, but at least some part of it doesn’t seem to work. First, let’s check the stats immediately after setting these variables, and then let’s push some additional data into the table, run an OPTIMIZE or two, delete some data, and see what happens:

mysql> set global innodb_ft_aux_table='test/dir_test_innodb';
mysql> set global innodb_optimize_fulltext_only=1;
mysql> select * from information_schema.innodb_ft_config;
+---------------------------+--------+                                                  
| KEY                       | VALUE  |                                                  
+---------------------------+--------+                                                  
| optimize_checkpoint_limit | 180    |                                                  
| synced_doc_id             | 787625 |                                                  
| last_optimized_word       |        |                                                  
| deleted_doc_count         | 0      |                                                  
| total_word_count          |        |                                                  
| optimize_start_time       |        |                                                  
| optimize_end_time         |        |                                                  
| stopword_table_name       |        |                                                  
| use_stopword              | 1      |
| table_state               | 0      |
+---------------------------+--------+
10 rows in set (0.00 sec)

mysql> insert into dir_test_innodb (full_name, details) 
       SELECT reverse(full_name), details FROM dir_test_innodb WHERE id < 500000; 
Query OK, 245051 rows affected (8 min 13.13 sec) 
Records: 245051  Duplicates: 0  Warnings: 0 

mysql> select * from information_schema.innodb_ft_config;
+---------------------------+---------+
| KEY                       | VALUE   |
+---------------------------+---------+
| optimize_checkpoint_limit | 180     |
| synced_doc_id             | 1028261 |
| last_optimized_word       |         |
| deleted_doc_count         | 0       |
| total_word_count          |         |
| optimize_start_time       |         |
| optimize_end_time         |         |
| stopword_table_name       |         |
| use_stopword              | 1       |
| table_state               | 0       |
+---------------------------+---------+
10 rows in set (0.02 sec)

mysql> optimize table dir_test_innodb;
+----------------------+----------+----------+----------+
| Table                | Op       | Msg_type | Msg_text |
+----------------------+----------+----------+----------+
| test.dir_test_innodb | optimize | status   | OK       |
+----------------------+----------+----------+----------+
1 row in set (4.60 sec)

mysql> select * from information_schema.innodb_ft_config;
+---------------------------+---------+
| KEY                       | VALUE   |
+---------------------------+---------+
| optimize_checkpoint_limit | 180     |
| synced_doc_id             | 1032677 |
| last_optimized_word       |         |
| deleted_doc_count         | 0       |
| total_word_count          |         |
| optimize_start_time       |         |
| optimize_end_time         |         |
| stopword_table_name       |         |
| use_stopword              | 1       |
| table_state               | 0       |
+---------------------------+---------+
10 rows in set (0.00 sec)

mysql> delete from dir_test_innodb LIMIT 200000;
Query OK, 200000 rows affected (8.65 sec)

mysql> optimize table dir_test_innodb;           
+----------------------+----------+----------+----------+
| Table                | Op       | Msg_type | Msg_text |
+----------------------+----------+----------+----------+
| test.dir_test_innodb | optimize | status   | OK       |
+----------------------+----------+----------+----------+
1 row in set (8.44 sec)

mysql> select * from information_schema.innodb_ft_config;
+---------------------------+---------+
| KEY                       | VALUE   |
+---------------------------+---------+
| optimize_checkpoint_limit | 180     |
| synced_doc_id             | 1032677 |
| last_optimized_word       |         |
| deleted_doc_count         | 0       |
| total_word_count          |         |
| optimize_start_time       |         |
| optimize_end_time         |         |
| stopword_table_name       |         |
| use_stopword              | 1       |
| table_state               | 0       |
+---------------------------+---------+

I ran OPTIMIZE TABLE several more times, and each execution took between 6 and 8 seconds, but the output of the query against I_S.innodb_ft_config never changed, so it seems like at least some of the diagnostic output isn’t working quite right. Intuitively, I would expect some changes in total_word_count, or optimize_(start|end)_time, and the like. However, if I check some of the other I_S tables, I do find that the number of rows in I_S.innodb_ft_index_table is changing, so it’s pretty clear that I do actually have a FT index available.

At the start of this post, I mentioned that I did make one configuration change to the default InnoDB settings for MySQL 5.6, and that was to change innodb_ft_min_token_size from the default of 3 to a value of 4 so that it would be identical to the MyISAM default. After all, the (naive?) hope here is that when I run an FTS query against both MyISAM and InnoDB I will get back the same results; if this equivalence doesn’t hold, then as a consultant, I might have a hard time recommending this feature to my customers, and as an end user, I might have a hard time using the feature at all, because it could completely alter the behavior of my application unless I also make a nontrivial number of code changes.

In part 2 of this series, we’ll reload and reset our SEO and DIR data sets back to their initial states, run some queries, and compare the output. Stay tuned, it gets rather curious.