Как я могу быстро искать записи / списки, используя несколько тегов? - PullRequest
0 голосов
/ 10 сентября 2018

Мой каталог сайта в настоящее время использует структуру таблицы "toxi" для маркировки списков.

Моя таблица сообщений содержит около 5 миллионов записей, а таблица карт - около 15 миллионов записей.

Я использую термины для хранения всех видов информации, таких как автор, издатель, тема, среда (например, аудио, видео и т. Д.). И сообщение может иметь несколько терминов для каждой таксономии (несколько авторов, несколько тем и т. Д.).

Поиск сообщений на основе одного term_id занимает около четырех секунд, чтобы вернуть результаты, что довольно паршиво, но это займет 40 секунд, чтобы вернуть результаты, используя несколько терминов.

Мне нужно более эффективное решение, но я не могу понять, являются ли мои запросы неэффективными или структура моей таблицы.

== ОДИН СРОК ПОИСКА ==

SELECT * FROM posts
LEFT JOIN post_taxonomy_term_map ON (posts.ID = post_taxonomy_term_map.object_id)
WHERE post_taxonomy_term_map.term_id=$term1

== ПОИСК НЕСКОЛЬКИХ УСЛОВИЙ ПОИСКА ==

SELECT p.*
FROM post_taxonomy_term_map m, posts p
WHERE m.term_id IN ($term1, $term2, $term3)
AND p.ID = m.object_id
GROUP BY p.ID
HAVING COUNT( p.ID )=3

СТОЛЫ И КОЛОННЫ

записей {ID, post_title и т. Д ...}

ПЕРВИЧНЫЙ ИД

taxonomy_terms {term_id, term_label, term_slug и т. Д.}

ПЕРВИЧНЫЙ term_id

post_taxonomy_term_map {map_id, object_id, taxonomy, term_id}

PRIMARY map_id

INDEX object_id

ИНДЕКС term_id

ИНДЕКС таксономии

ПРИМЕЧАНИЕ: post_taxonomy_term_map.object_id относится к значению posts.ID

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Вероятно, основная проблема с производительностью связана с таблицей «многие: многие», которую запрашивает TOXI. Можно устранить:

CREATE TABLE Tags (
    tag VARHAR(...) NOT NULL,
    bid INT ... NOT NULL,
    PRIMARY KEY(tag, bid),
    INDEX(bid, tag)
)

Примечания:

  • Это лучше, чем TOXI, поскольку он не проходит через таблицу «многие: многие», что затрудняет оптимизацию.
  • Конечно, мой подход может быть немного более громоздким (чем TOXI) из-за избыточных тегов, но это небольшой процент от всей базы , и улучшения производительности могут быть значительными.
  • Это очень масштабируемый.
  • У него нет (потому что оно не нужно) суррогата AUTO_INCREMENT PK. Следовательно, это лучше, чем Скаттл.
  • MySQLicious отстой, потому что он не может использовать индекс (LIKE с ведущий подстановочный знак; ложные попадания в подстроки)
  • Для MySQL обязательно используйте ENGINE = InnoDB, чтобы получить эффекты «кластеризации».

Связанные обсуждения (для MySQL):
много: много таблиц оптимизации оптимизация ,
упорядоченные списки ,
и, особенно для пользователей WP, постмета улучшений

0 голосов
/ 10 сентября 2018

Для вашего первого запроса:

SELECT *
FROM posts
LEFT JOIN post_taxonomy_term_map
    ON posts.ID = post_taxonomy_term_map.object_id
WHERE post_taxonomy_term_map.term_id = $term1

составной индекс по (term_id, object_id). Этот индекс включает term_id, который уже выполнялся одним или вашими индексами, но он также охватывает объединение, включая object_id. Предполагая, что предложение WHERE считается достаточно ограничительным для оптимизатора, чтобы использовать индекс, это должно работать лучше, чем у вас есть в настоящее время.

CREATE INDEX some_idx ON post_taxonomy_term_map(term_id, object_id);
...