我已将Web服务器access_log转换为mysql表,如下所示:
CREATE TABLE `access_log` (
`timestamp` int(11) NOT NULL default '0',
`visitorid` int(11) default NULL,
`url` int(11) default NULL,
`params` int(11) default NULL,
`status` smallint(3) NOT NULL default '0',
`bytes` int(20) NOT NULL default '0',
`referrer` int(11) default NULL,
`refparams` int(11) default NULL,
`useragentid` int(11) default NULL,
`keywords` int(11) default NULL,
`country` char(3) default '',
`crawl` int(1) NOT NULL default '0',
`sessionid` int(11) default NULL,
KEY `timestamp` (`timestamp`),
KEY `visitorid` (`visitorid`),
KEY `url` (`url`),
KEY `referrer` (`referrer`),
KEY `keywords` (`keywords`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 PACK_KEYS=1;
我有一个查询,可以针对特定日期范围生成“最热门页面”报告,示例如下:
select url,
count(distinct visitorid) as visitors,
count(*) as hits
from access_log where
timestamp >=1270072800 and timestamp <=1272664799
and crawl=0
group by url order by visitors desc limit 100;
当表中有大量记录时,此查询会变得非常慢。
根据相对于表中记录总数的时间戳范围,优化器会说它将使用“timestamp”或“url”键。但是,它总是提到'使用在哪里;使用临时;使用filesort'
有没有什么方法可以创建一个可以改善此查询执行时间的组合索引?
我尝试了以下组合,但优化器似乎忽略了它们:
对于我所缺少的任何建议或指示都将不胜感激。
谢谢!
答案 0 :(得分:0)
因此,您希望在给定时间段内按受欢迎程度对网址进行排名。 (URL,visitorid)上的复合索引会让你受欢迎。 (timestamp,url)上的复合索引将为您提供在期间访问的网址。为什么不尝试两个索引,并对内联视图进行连接,这样的事情(不确定mysql中内联视图的确切语法):
select distinct URL from log as Log1
where visitdatetime > x and visitdatetime< y
join
(select url, count(distinct visitorid) as DistinctVisitors
from log
group by url
-- having count(distinct visitorid) > {some cutoff value greater than 1}
-- try the composite index (url, visitorid, visitdate)
having vistdate > x and visitdate < y
) as Log2
on Log1.url = log2.url
order by DistinctVisitors desc
答案 1 :(得分:0)
将访问日志分区为多个表,并仅对日期范围内的表运行此查询。
使用每日/每周/每月基础预先汇总的数据制作汇总表,以减少必须用于生成报告的数据量。因此,在导入当天的日志文件后,通过将时间戳划分为小时边界,然后降低到日期边界等来聚合数据。