mysql - 聚集索引还是分区表?

标签 mysql sql

我有一个文件共享网站,我的用户对点击他们的文件感兴趣。每次点击都会作为新行存储在点击表中。

通常,他们想知道在特定日期范围内获得了多少点击:

$statement = $db->prepare("SELECT COUNT(DISTINCT ip) FROM clicks WHERE user_id=? AND time BETWEEN ? AND ?");
$statement->execute(array($user_id, $from_date, $to_date));

此外,他们还可以查看特定文件的点击次数:

$statement = $db->prepare("SELECT COUNT(DISTINCT ip) FROM clicks WHERE file_id=? AND time BETWEEN ? AND ?");
$statement->execute(array($file_id, $from_date, $to_date));

这些查询的问题是 user_id 和 file_id 不是该表的键(它们不是唯一的)。相反,一个简单的“id”列是主键,但它永远不会参与任何查询。

我一直在研究聚集索引,但我不知道如何在这种情况下实现它。

随着点击表变得相当大(5-600 万行),这些查询需要更长的时间(并且我计划让该表变得更大)。我读到分区可能是我需要做的?

我需要创建聚集键、对表进行分区,还是两者都创建?

作为引用,clicks 结构:

id 时间 user_id ip file_id

最佳答案

您不需要更改聚集索引。

我建议创建这些索引:

ALTER TABLE clicks ADD INDEX (file_id, time, ip),
                   ADD INDEX (user_id, time, ip);

通过在索引定义中包含 ip,每个查询应该能够从索引结构本身获取所需的所有信息。这称为覆盖索引。然后查询根本不需要接触表,因此哪些列构成表的聚集索引并不重要。

如果您使用 EXPLAIN 来分析查询,您应该在 Extra 字段中看到“Using index”,这表明查询正在受益于覆盖索引。

我认为分区在这种情况下没有帮助,因为 MySQL 分区要求分区列必须是表的任何主键/唯一键的一部分。

关于mysql - 聚集索引还是分区表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13852052/

相关文章:

php - yii2中的sql查询

MySQL 获取减法的返回值

sql - 表是否会在更改表删除列时被删除并重新创建?

sql - 与简单或条件相比,在条件中使用效率极低

sql - rails : How to sum and display total quantity by category

mysql - 不确定如何为以下任务构建 SQL 查询

使用外键按层次结构排序的 mySQL 查询

android - 应用程序退出,很难找到原因

php - Magento - 高级产品导入

php - 从数据库验证中选择列表