我正在尝试使此查询正常工作,该查询为对多个标签(又称为酒吧)感兴趣的用户获取供稿。 user和tag的映射在user_pub表中,并且帖子本身具有pub_id。下面的模式。
CREATE TABLE `post` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`pub_id` bigint(20) unsigned NOT NULL,
`author_id` bigint(20) unsigned NOT NULL,
`snippet` text COLLATE utf8mb4_unicode_ci,
`type` tinyint(3) unsigned NOT NULL,
`status` tinyint(3) unsigned NOT NULL DEFAULT '1',
`time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `time_idx` (`time`),
KEY `fk_author_id_idx` (`author_id`),
KEY `idx_pub_status_type_author` (`pub_id`,`type`,`status`,`author_id`)
) ENGINE=InnoDB AUTO_INCREMENT=299521 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
CREATE TABLE `user_pub` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned NOT NULL,
`pub_id` bigint(20) unsigned NOT NULL,
`join_status` tinyint(4) NOT NULL DEFAULT '1',
`time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_unq_up_user_pub` (`user_id`,`pub_id`)
) ENGINE=InnoDB AUTO_INCREMENT=227392 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
查询很简单:
SELECT p.*
FROM post p
INNER JOIN user_pub up ON up.pub_id = p.pub_id
WHERE up.user_id = 1234
ORDER BY p.id DESC LIMIT 10;
没有ORDER BY,速度很快(0.5ms),说明看起来还可以:
+----+-------------+-------+----------------------------+----------------------------+---------+-----------------------+------+----------+-------------+
| id | select_type | table | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+----------------------------+----------------------------+---------+-----------------------+------+----------+-------------+
| 1 | SIMPLE | up | idx_unq_up_user_pub | idx_unq_up_user_pub | 8 | const | 2 | 100.00 | Using index |
| 1 | SIMPLE | p | idx_pub_status_type_author | idx_pub_status_type_author | 8 | thedb.up.pub_id | 64 | 100.00 | NULL |
+----+-------------+-------+----------------------------+----------------------------+---------+-----------------------+------+----------+-------------+
使用ORDER BY,大约需要70毫秒,并说明具有使用索引;使用临时;在EXTRA中使用文件排序:
+----+-------------+-------+----------------------------+----------------------------+---------+-----------------------+------+----------+----------------------------------------------+
| id | select_type | table | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+----------------------------+----------------------------+---------+-----------------------+------+----------+----------------------------------------------+
| 1 | SIMPLE | up | idx_unq_up_user_pub | idx_unq_up_user_pub | 8 | const | 2 | 100.00 | Using index; Using temporary; Using filesort |
| 1 | SIMPLE | p | idx_pub_status_type_author | idx_pub_status_type_author | 8 | thedb.up.pub_id | 64 | 100.00 | NULL |
+----+-------------+-------+----------------------------+----------------------------+---------+-----------------------+------+----------+----------------------------------------------+
我尝试像这样重写此查询,但这没有影响:
SELECT p1.*
FROM post p1,
(SELECT p.id
FROM post p, user_pub up
WHERE up.user_id = 1234 AND up.pub_id = p.pub_id
) p2
WHERE p1.id = p2.id
ORDER BY p1.id DESC LIMIT 10;
总结:
表不是很大,每个表大约有25万行。