改进MySQL慢查询

时间:2014-03-31 16:00:43

标签: mysql query-optimization

我正在使用新遗物来诊断和修复我们数据库的性能问题。所以我有以下最耗时的查询。

SELECT * FROM `page_view` 
WHERE `ip_address` = ?s 
  AND `param` = ?n 
  AND NOW() < DATE_ADD(`date`, INTERVAL 1 DAY);

表结构如下:

CREATE TABLE `page_view` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_pages` varchar(255) NOT NULL,
  `id_user` int(11) NOT NULL DEFAULT '0',
  `param` varchar(255) NOT NULL DEFAULT '',
  `contract_id` int(10) NOT NULL,
  `listing_type_sid` int(11) DEFAULT NULL,
  `ip_address` varchar(255) DEFAULT NULL,
  `date` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `id_pages` (`id_pages`),
  KEY `id_user` (`id_user`),
  KEY `param` (`param`),
  KEY `contract_id` (`contract_id`)
) ENGINE=MyISAM AUTO_INCREMENT=207 DEFAULT CHARSET=utf8;

在处理查询方面,我是一个新手,但我很欣赏任何改善这个问题的技巧。

感谢。

2 个答案:

答案 0 :(得分:2)

实施适当的索引。

如果可能,当裸列上的等效谓词可用时,不要在谓词中的表达式中包装列。例如,这个:

NOW() < DATE_ADD(`date`, INTERVAL 1 DAY);

可以替换为:

`date` > NOW() + INTERVAL -1 DAY

使用后一种形式,右侧会被评估一次,并成为一个文字,MySQL可以考虑date列上的索引范围扫描操作来满足谓词。

使用前一个表单,这迫使MySQL评估右侧的表达式,并将结果与​​每一行的文字进行比较(或者至少是每个未被其他谓词过滤掉的行)。

此查询最合适的索引是使具有等式谓词前导的列,后跟具有不等式的列:

... ON page_view (ip_address, param, `date`)

答案 1 :(得分:1)

假设你的表中有很多行,但只有一些行与给定的IP地址有关,并且提出一个可能有助于加速查询的建议: 在where子句中的字段上创建组合索引:

create index myindex on page_view(ip_address, param, date)

然后将日期算术从日期字段移开(从现在开始减去一天而不是将其添加到日期列)。 新索引可能会降低插入速度,因为必须管理新索引。