mysql - 用于计算每个邮箱未读电子邮件数量的数据库架构

标签 mysql sql mariadb

我正在构建一个电子邮件网络应用程序,但在想出一个能够快速计算每个文件夹未读电子邮件数量的架构时遇到了困难。

我目前的架构如下所示:

CREATE TABLE emails(id INT, user_id INT, folder INT, 
    read_on TIMESTAMP, raw_email_filename VARCHAR(128));

要获取每个文件夹的未读计数,我可以运行如下查询:

SELECT count(*) FROM email WHERE user_id =? AND folder IN (?..) AND read_on IS NULL;

但是,鉴于我的索引是(user_id,文件夹),这必须遍历每个文件夹上的所有电子邮件才能获取计数。

我正在考虑添加一个索引(user_id,folder, read_on),但是当我只对感兴趣时,read_on的条目太多了read_on 的 code>NULL 值。

有更好的方法吗?也许通过非规范化?在 Redis 中进行计数或者其他什么?

最佳答案

我会考虑

INDEX(user_id, read_on, folder)

构建最佳索引的准则是首先列出用=测试的列(IS NULL也算这样),然后INs(文件夹),然后是一个范围(您没有任何范围)。

不必担心 read_on IS NOT NULL 条目的索引条目被浪费;它们会使磁盘变得困惑,但不会影响性能。

另一方面,当您更改 read_on(通过 UPDATE?)时,会受到轻微影响,因为我建议的 INDEX 中的一个条目> 需要从索引 BTree 中的一个位置移动到另一个位置。同样,这可能不值得担心。

您不想使用GROUP BY吗?

SELECT folder, COUNT(*)
    FROM emails
    WHERE user_id = ?
      AND folder IN (...)
      AND read_on IS NULL
    GROUP BY folder;

执行解释选择...。对于我的 INDEXEXPLAIN 可能会说 Using index,表示“覆盖”索引。这就是所有所需的列都在索引中的地方。

有关索引创建的更多信息:http://mysql.rjweb.org/doc.php/index_cookbook_mysql

关于mysql - 用于计算每个邮箱未读电子邮件数量的数据库架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55909083/

相关文章:

mysql - 为什么 MySQL 要求参数按特定顺序排列?

mysql - sql 获取具有最大日期和相对 id 记录的行

mysql - 使用 MySQL 或 MariaDB 存储位置

mysql - MariaDB 的 TIMESTAMP、CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP 错误

mysql - 如何使用 SQL 检索 drupal DB 中的垃圾评论并删除它们?

php - mysqli_fetch_object 和 $res->fetch_object 之间的区别

sql - 具有参数 CTE 表达式结果的表值函数

sql - 最好的 Oracle SQL 查询分析工具

php - PDO 重复更新错误

php - mysql SELECT with 'A' from php array 不起作用(因为 php 和 mysql 中的 `A` 看起来相同,但一个用俄语写,另一个用英语写)