如何为后续查询创建有效索引

时间:2010-12-06 17:02:20

标签: sql mysql

我已将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'

有没有什么方法可以创建一个可以改善此查询执行时间的组合索引?

我尝试了以下组合,但优化器似乎忽略了它们:

  1. IDX(时间戳,URL,visitorid,爬行)
  2. IDX(URL,visitorid,爬行,时间戳)
  3. 对于我所缺少的任何建议或指示都将不胜感激。

    谢谢!

2 个答案:

答案 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)

将访问日志分区为多个表,并仅对日期范围内的表运行此查询。

使用每日/每周/每月基础预先汇总的数据制作汇总表,以减少必须用于生成报告的数据量。因此,在导入当天的日志文件后,通过将时间戳划分为小时边界,然后降低到日期边界等来聚合数据。