mysql - 如果一列非常频繁,则mysql中的复合索引

标签 mysql indexing

我有一个表,其中包含多个租户的数据。

CREATE TABLE `accountPost` (
 `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
 `tenantId` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '',
 `accountId` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
 `scheduledTime` BIGINT(19),
 ......more columns
 PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=781625 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

这里,scheduledTime 是时间戳。 tenantId 对于许多 accountPost 行来说是常见的。

现在,我有一个类似的查询

select * from accountPost
    where scheduledTime > t1
      and scheduledTime < t2
      and tenantId = "x";

对于这个查询,我想创建一个复合索引。

1. ALTER TABLE `accountPost` ADD INDEX `idx1` (`scheduledTime`, `tenantId`);
2. ALTER TABLE `accountPost` ADD INDEX `idx1` (`tenantId`, `scheduledTime`);

我应该使用这两者中的哪一个来获得插入和读取的最佳性能,为什么? 是否应该将更频繁的列添加为复合索引中的第一个列?

最佳答案

综合指数的各个组成部分的基数是无关紧要的。

重要的是输入 = < 之前的列(等)列。所以这必然是更好的顺序:

INDEX(`tenantId`, `scheduledTime`)

(同时,WHERE 中子句的顺序并不重要。)

至于读与写... SELECT良好索引的好处远远超过写入(插入/更新/删除)的微小开销。添加读取所需的所有索引;丢弃任何冗余或从未使用过的索引。那么不用担心。

比较日期(或日期时间)的提示:谨防 BETWEEN或者,在您的示例中,<> -- 它们包含或排除两个端点。我喜欢以下模式:

WHERE dt >= '2019-12-27'
  AND dt  < '2019-12-27' + INTERVAL 7 DAY

模式提示:考虑使用较小的数据类型。 255很方便,但有一些小的性能问题。 BIGINT (8 字节)几乎总是比需要的大。大小对于磁盘空间和缓存很重要。

你从哪里得到的BIGDECIMAL ??

更多:http://mysql.rjweb.org/doc.php/index_cookbook_mysql

关于mysql - 如果一列非常频繁,则mysql中的复合索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59633161/

相关文章:

Mysql带循环查看表

performance - 如何处理对 Lucene 索引的非常频繁的更新

MySQL索引名称和外键名称必须针对不同的表不同吗?

javascript - 如何在 jQuery 中使用索引?

php - 将 'check username' 添加到注册表 PHP

mysql - 即使使用带有内部连接的 Distinct 关键字,也会出现重复值

php - 优化此 SQL 查询

mysql - MySQL显示rownum问题

arrays - 如何在Fortran中访问数组中的最后一项?

c - 在 C 中查找数组的索引