我正在使用新遗物来诊断和修复我们数据库的性能问题。所以我有以下最耗时的查询。
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;
在处理查询方面,我是一个新手,但我很欣赏任何改善这个问题的技巧。
感谢。
答案 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)
然后将日期算术从日期字段移开(从现在开始减去一天而不是将其添加到日期列)。 新索引可能会降低插入速度,因为必须管理新索引。