Chr*_*ker 10 php sql performance join large-data
我有一个庞大的艺术家,专辑和曲目数据库.这些项目中的每一个都可以通过胶合表(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) |
Run Code Online (Sandbox Code Playgroud)
编辑我正在使用PHP,我不反对在脚本中进行任何排序或其他hijinx,我的#1关注点是返回速度.
您可能应该尝试对数据进行非规范化。您的结构针对插入/更新负载进行了优化,但不适用于查询。据我所知,您将拥有比插入/更新查询更多的选择查询。
例如你可以这样做:
以规范化结构存储数据。
像这样创建聚合表
track_id, artist_tags, album_tags, track_tags
1 , jazz/pop/, jazz/rock, /heavy-metal/
or
track_id, artist_tags, album_tags, track_tags
1 , 1/2/, 1/3, 4/
Run Code Online (Sandbox Code Playgroud)
为了加快搜索速度,您可能应该在 *_tags 列上创建 FULLTEXT 索引
使用 sql 查询该表,例如
select * from aggregate where album_tags MATCH (track_tags) AGAINST ('rock')
Run Code Online (Sandbox Code Playgroud)
每天增量重建该表一次。