mysql - 带标签和 GROUP_CONCAT 的产品 View

标签 mysql view tags group-concat

我在我的应用程序上使用 Sphinx 进行全文搜索。我使用 view 来过滤 products 表中的数据,并为该 View 建立索引。现在,我在产品表下有一个硬编码字段及其相关标签,但这不太好,因为标签可能会更改,而且我每次都必须操作硬编码字段。

所以我想我可以使用 GROUP_CONCAT 创建 View ,使用如下语法列出所有相关标签:

SELECT p.id AS id, GROUP_CONCAT(t.tag SEPARATOR '|') AS tags,
UNIX_TIMESTAMP(p.created) AS created
FROM products p
INNER JOIN products_tags pt ON pt.product_id = p.id
INNER JOIN tags t ON t.id = pt.tag_id
AND p.deleted = 0
AND (p.images IS NOT NULL OR p.images <> '')
AND p.status LIKE 'listed'
GROUP BY p.id;

此查询的问题在于它需要很长时间才能运行。真的很慢。如果只检索一条记录,最多需要 5 秒。这是 EXPLAIN 输出:

1, SIMPLE, pt, ALL, , , , , 165029, Using temporary; Using filesort
1, SIMPLE, p, eq_ref, PRIMARY, PRIMARY, 4, trych_default.pt.product_id, 1, Using where
1, SIMPLE, t, eq_ref, PRIMARY, PRIMARY, 4, trych_default.pt.tag_id, 1, 

我想知道是否有任何方法可以改进查询,或者可能有更好的解决方案来解决我的问题。谢谢!

最佳答案

您可能缺少索引。使用以下架构,相同的查询命中每个表的索引:

CREATE TABLE `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `deleted` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `status` varchar(255) NOT NULL DEFAULT 'listed',
  `images` varchar(255) DEFAULT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `tags` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `tag` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `products_tags` (
  `product_id` int(11) NOT NULL,
  `tag_id` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`product_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

以下是 EXPLAIN 查询的结果:

EXPLAIN SELECT p.id AS id, GROUP_CONCAT(t.tag SEPARATOR '|') AS tags,
UNIX_TIMESTAMP(p.created) AS created
FROM products p
INNER JOIN products_tags pt ON pt.product_id = p.id
INNER JOIN tags t ON t.id = pt.tag_id
WHERE p.deleted = 0
AND (p.images IS NOT NULL OR p.images <> '')
AND p.status LIKE 'listed'
GROUP BY p.id;

+----+-------------+-------+--------+---------------+---------+---------+----------------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref            | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+----------------+------+-------------+
|  1 | SIMPLE      | p     | index  | PRIMARY       | PRIMARY | 4       | NULL           |    1 | Using where |
|  1 | SIMPLE      | pt    | ref    | PRIMARY       | PRIMARY | 4       | test.p.id      |    1 | Using index |
|  1 | SIMPLE      | t     | eq_ref | PRIMARY       | PRIMARY | 4       | test.pt.tag_id |    1 |             |
+----+-------------+-------+--------+---------------+---------+---------+----------------+------+-------------+
3 rows in set (0.00 sec)

关于mysql - 带标签和 GROUP_CONCAT 的产品 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5994338/

相关文章:

jquery - 激活和停用超链接

mysql - Ejabberd:将 Mnesia "passwd"表迁移到 MySQL "user"表

mysql - 如何从 MySQL 中的多个表中删除?

php - #1045 无法登录 MySQL 服务器

mysql - 选择一个记录,除了一个

Android:从自定义 View 处理后退按钮

javascript - Google VR 网页版

安卓: "zoom to fill screen"和 "strech to fill screen"

tags - terraform 覆盖子模块中的标签值

javascript - 正则表达式更改 html 标签内的文本