0

I have two MySQL queries which I use to help me arrange news on my website. All the fields here indicated are numeric (int or tinyint) and all have an index on them. Can somebody help me build the multi column indexes which will speed up the two queries please?

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

And here is the DB schema:

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`),
);
4

1 回答 1

1

索引并不总是答案(尤其是在INSERT需要许多语句的情况下)。话虽如此,您可以做几件事来优化这些查询:

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

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

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

于 2012-08-14T19:08:31.233 回答