我在我的应用程序上使用 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/