如何快速筛选出部门下某用户未读的信件数?

2021-05-06 18:22:32 +08:00
 xx19941215

有三张表 t_letter :表示信件表 ( 60 万数据)索引如下:

t_letter_dep_map:部门的信件的关联表 ( 30 万数据) 结构如下

索引如下:

t_read:已读的数据表( 150 万数据,因为我们这个信件是区分很多状态的 比如待受理 下用户是否已读 和已受理下用户是否已读是要分开对待的,所以数据会比信件表多很多)

结构如下

索引如下:

我最开始写的 SQL 如下:

SELECT count(distinct `t_letter`.`id`)
FROM `t_letter`
	LEFT JOIN `t_letter_dep_map` `t_l_d_m` ON `t_l_d_m`.`depable_id` = `t_letter`.`id`
WHERE `t_letter`.`site_id` = 145
	AND `del_status` = 0
	AND (`letter_dep_id` = 206
		AND `depable_type` = 9)
	AND (`t_letter`.`id` NOT IN (
			SELECT `readable_id`
			FROM `t_read`
			WHERE `user_id` = 33203
				AND `cat` = 'all'
				AND `readable_type` = 9
		)
		AND `t_letter`.`time` > 1619402413)
	AND `t_letter`.`deleted_at` IS NULL
	

表示筛选出分配给部门 id 为 206 的并且用户 id 为 33203 在‘all’分类下还没有读的信件总数,这条 sql 耗时大概为 10s 。 explain 信息如下:

我参照网上的教程,讲 sql 改为 left join 之后情况也没有太大变化,耗时也是 10 秒左右

SELECT count(distinct `t_letter`.`id`)
FROM `t_letter`
	LEFT JOIN `t_letter_dep_map` `t_l_d_m` ON `t_l_d_m`.`depable_id` = `t_letter`.`id`
	LEFT JOIN (select * from `t_read` where `user_id` = 33203 and `cat` = 'all' and `readable_type` = 9) as `t_r` on `t_r`.`readable_id` = `t_letter`.`id`
WHERE `t_letter`.`site_id` = 145
	AND `del_status` = 0
	AND (`letter_dep_id` = 206
		AND `depable_type` = 9)
	AND 
		`t_r`.`readable_id` is null

		AND `t_letter`.`time` > 1619402413
	AND `t_letter`.`deleted_at` IS NULL

但是我在删除了部门的信件关联表之后,速度就变得很快,

SELECT count(distinct `t_letter`.`id`)
FROM `t_letter`
WHERE `t_letter`.`site_id` = 145
    AND `del_status` = 0
    AND (`t_letter`.`id` NOT IN (
            SELECT `readable_id`
            FROM `t_read`
            WHERE `user_id` = 33203
                AND `cat` = 'all'
                AND `readable_type` = 9
        )
        AND `t_letter`.`time` > 1619402413)
    AND `t_letter`.`deleted_at` IS NULL

只需要

这么短,那如何快速筛选出部门下某用户未读的信件数呢?

637 次点击
所在节点    问与答
3 条回复
xx19941215
2021-05-06 18:57:43 +08:00
我发现主要是 left join t_letter_dep_map 这个表非常慢
xx19941215
2021-05-06 18:59:22 +08:00
但是不这样做 又没办法满足需求 怎么弄呢
xx19941215
2021-05-06 19:30:27 +08:00
谢谢大家 是因为 t_letter_dep_map 有一个字段的类型设置错误了 导致无法使用索引 。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/775252

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX