MySQL,多列索引

标签 mysql indexing

我有两个 MySQL 查询,用于帮助我在网站上安排新闻。此处指示的所有字段都是数字(int 或tinyint),并且都有索引。有人可以帮助我构建多列索引来加速两个查询吗?

SELECT MAX(content_time) AS content_time 
  FROM cm_data 
 WHERE content_time < UNIX_TIMESTAMP() 
   AND page = '1' 
   AND (content_type = '1' OR content_type = '5')

SELECT content_id 
  FROM cm_data
 WHERE (content_time < UNIX_TIMESTAMP() 
       OR (hp_time >= UNIX_TIMESTAMP() AND content_time < UNIX_TIMESTAMP()
          )
       )
   AND page = '1' 
   AND (content_type = '1' OR content_type = '5')
 ORDER BY hp_time DESC
     , content_time DESC
 LIMIT 20

这是数据库架构:

CREATE TABLE IF NOT EXISTS `cm_data` (
  `content_id` mediumint(8) NOT NULL AUTO_INCREMENT,
  `content_time` int(11) DEFAULT NULL,
  `hp_time` int(11) NOT NULL DEFAULT '0',
  `content_type` tinyint(2) DEFAULT NULL,
  `page` tinyint(2) NOT NULL DEFAULT '1',
  PRIMARY KEY (`content_id`),
  KEY `content_time` (`content_time`),
  KEY `content_type` (`content_type`),
  KEY `page` (`page`),
);

最佳答案

索引并不总是答案(尤其是在需要许多 INSERT 语句的情况下)。话虽这么说,您可以采取一些措施来优化这些查询:

1) 确保您的约束格式正确。在第二个查询中,本质上是 Case1 OR ( Case2 AND Case1 ),它可以简化为 Case1 ( bool 代数)。确保在查询优化器查看之前尽可能减少这些问题,不仅可以减少优化器所需的工作量,还可以捕获它无法解决的情况。

2) 检查约束的顺序。由于文档中没有任何地方说明查询优化器将以任何特定顺序检查非唯一键的约束,因此可以使用一些优化知识来潜在地加快查询速度。一般来说,非整数约束的评估成本很高(字符串等)。在您的情况下,UNIX_TIMESTAMP() 返回一个 UNSIGNED INT,而该字段被指定为 INTEGER。这将导致对每一行进行强制转换操作,这将是昂贵的。因此,如果您可以减少必须进行比较的次数(通过首先过滤掉具有较简单约束的行),则必须执行的操作就会减少,从而缩短执行时间。

2a) MySQL 不支持函数索引,因此您可以将字段的数据类型更改为 UNSIGNED INT(如果可用则首选),或者创建一个附加列,该列使用包含 UNSIGNED INT 等效项的触发器进行更新字段的名称,并为其建立索引。后者并不理想,但可以通过增加表大小来提高性能。

关于MySQL,多列索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11956203/

相关文章:

search - Elasticsearch 中的索引和搜索分析器:将准确的字符串作为第一个结果时遇到麻烦

sql - 优化行排除查询

python - 不支持身份验证插件 'caching_sha2_password'

mysql - 在 php 中编辑和更新文本区域

mysql - EPERM : operation not permitted error : Prisma . 输入命令后 'npx migrate dev --name init'

java - 在 Arraylist 中搜索时遇到问题

php - vbulletin 4 搜索不起作用

PHP数组变成一个字符串

python - Python 中的数组索引

sql - Oracle 保留唯一约束索引