Высокопроизводительная многоуровневая фильтрация тегов

У меня большая база данных исполнителей, альбомов и треков. Каждый из этих элементов может иметь один или несколько тегов, назначенных через таблицы склеивания (track_attributes, album_attributes, artist_attributes). Есть несколько тысяч (или даже сотен тысяч) тегов, применимых к каждому типу элементов.

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

Задача 1) Получить все треки, которые имеют какие-либо заданные теги (если предоставлены) от исполнителей, у которых есть какие-либо заданные теги (если предоставлены) в альбомах с любыми заданными тегами (если предоставлены). Любой набор тегов может отсутствовать (т. Е. Активен только тег трека, без тегов исполнителя или альбома)

Вариант: результаты также отображаются по исполнителю или по альбому, а не по треку.

Задача 2) Получить список тегов, которые применяются к результатам из предыдущего фильтра, вместе с подсчетом количества дорожек, имеющих каждый данный тег.

То, что мне нужно, - это некоторые общие рекомендации по подходу . Я пробовал временные таблицы, внутренние соединения, IN (), все мои усилия до сих пор приводили к медленным ответам. Хороший пример результатов, которых я добиваюсь, можно увидеть здесь: http://www.yachtworld.com/core/listing/advancedSearch.jsp , за исключением , у них только один уровень тегов, я имею дело с тремя.

Структуры таблиц:

Table: attribute_tag_groups
   Column   |          Type               |   
------------+-----------------------------+
 id         | integer                     |
 name       | character varying(255)      | 
 type       | enum (track, album, artist) | 

Table: attribute_tags
   Column                       |          Type               |   
--------------------------------+-----------------------------+
 id                             | integer                     |
 attribute_tag_group_id         | integer                     |
 name                           | character varying(255)      | 

Table: track_attribute_tags
   Column   |          Type               |   
------------+-----------------------------+
 track_id   | integer                     |
 tag_id     | integer                     | 

Table: artist_attribute_tags
   Column   |          Type               |   
------------+-----------------------------+
 artist_id  | integer                     |
 tag_id     | integer                     | 

Table: album_attribute_tags
   Column   |          Type               |   
------------+-----------------------------+
 album_id   | integer                     |
 tag_id     | integer                     | 

Table: artists
   Column   |          Type               |   
------------+-----------------------------+
 id         | integer                     |
 name       | varchar(350)                | 

Table: albums
   Column   |          Type               |   
------------+-----------------------------+
 id         | integer                     |
 artist_id  | integer                     | 
 name       | varchar(300)                | 

Table: tracks
   Column    |          Type               |   
-------------+-----------------------------+
 id          | integer                     |
 artist_id   | integer                     | 
 album_id    | integer                     | 
 compilation | boolean                     | 
 name        | varchar(300)                | 

РЕДАКТИРОВАТЬ Я использую PHP, и я не против использования какой-либо сортировки или другого хиджинкс в скрипте, моя проблема №1 - скорость возврата .

10
задан Community 22 September 2017 в 17:44
поделиться