Оптимизация запроса с помощью fts + составной индекс - PullRequest
0 голосов
/ 18 января 2020

У меня есть следующий запрос:

SELECT * 
FROM table 
WHERE 
    structural_type=1 
    AND parent_id='167F2-F' 
    AND points_to_id=''
    # AND match(search) against ('donotmatch124213123123')

Поиск занимает около 10 мсек, выполняется по составному индексу (Structure_type, parent_id, points_to_id). Однако, когда я добавляю в индекс fts, запрос увеличивается на ~ 1 с, независимо от того, что содержится в критериях соответствия. По сути, кажется, что он «пропускает индекс» всякий раз, когда у меня применяется поиск fts.

Каков наилучший способ оптимизации этого запроса?

Обновление : a некоторые объясняют:

EXPLAIN SELECT... # without fts

id  select_type table   partitions  type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  table   NULL    ref structural_type structural_type 209 const,const,const   2   100.00  NULL

С помощью fts (также добавляется «индекс силы»):

explain SELECT ... force INDEX (structural_type) AND match...

id  select_type table   partitions  type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  table   NULL    fulltext    structural_type,search  search  0   const   1   5.00    Using where; Ft_hints: sorted

Единственное, о чем я могу думать, это невероятно взломать-i sh, было бы добавить дополнительный термин для fts, так что это делает фильтр «внутри» этого. Например:

fts_term = fts_term += " StructuralType1ParentID167F2FPointsToID"

Ответы [ 2 ]

0 голосов
/ 18 января 2020

Оптимизатор MySQL может использовать только один индекс для вашего предложения WHERE, поэтому ему приходится выбирать между составным и FULLTEXT.

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

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

Выполнение запроса OPTIMIZE TABLE table позволяет MySQL обновить sh его статистику таблицы, поэтому он сможет лучше оценивать и выбирать лучший индекс.

0 голосов
/ 18 января 2020

Попробуйте выразить это без полнотекстовой логики c, используя like:

SELECT * 
FROM table 
WHERE structural_type = 1 AND
      parent_id  ='167F2-F' AND
      points_to_id = '' AND
      search not like '%donotmatch124213123123%';

Индекс все еще следует использовать для первых трех столбцов. LIKE может быть медленным, но если не много строк соответствуют первым трем, это может быть не так плохо, как использование полнотекстового индекса.

...