我现在在做一个统计程序,数据库是这样设计的
CREATE TABLE IF NOT EXISTS `".$tname."` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`l` varchar(1000) default '',//来路页面
`s` varchar(1000) default '',//受访页面
`ym` varchar(150) default '',//受访域名
`uip` INT( 11 ) NULL DEFAULT '0',//用户ip地址
`uid` INT( 11 ) NULL DEFAULT '0',//用户编号
`bid` varchar( 100 ) NULL DEFAULT '0',//浏览器
`utime` INT( 11 ) NULL DEFAULT '0'//访问时间
) ENGINE=MyISAM DEFAULT CHARSET=gbk AUTO_INCREMENT=1 ;
现在每天的统计的数据量在800万-1000万条
我需要查询每天受访域名、受访页面、浏览器等这些信息(类似cnzz网站统计的效果,在查询中用到了group)。在查询的时候相当慢,打开页面等很久也显示不出来数据。请问各位有没有什么好的方法的?不管是数据库设计方面还是sql语句方面都可以给我说说,谢谢了。小弟不胜感激!

解决方案 »

  1.   

    查询很慢,贴出你的查询语句。
    另外show index from `".$tname."` 看看索引情况。
      

  2.   

    对varchar列进行group应该是不可取的,可以将其int化,为各个domain指定int值。对int索引后,再次count group应该会好不少。
      

  3.   

    查询语句
    $sql="select count(s) as c from stat_20101105 group by s";show index from stat_20101105结果如下:
    table->stat_20101105
    non_union->0
    key_name->primary
    seq_in_index->1
    colunm_name->id
    callation->a
    cardinality->7146648
    sub_part->
    packed->
    null->
    index_type->btree
    comment->
      

  4.   

    针对这个查询,在S字段上面加个索引。
    CREATE INDEX part_of_s ON stat_20101105(s(10));
      

  5.   

    我把数据删除到只剩下100万条,然后给s添加了索引,查询语句如下:
    select s,count(s) as c  from c group by s order by c desc limit 50
    第一次执行时间为1分钟左右,刷新执行,时间为0.00
      

  6.   

    第一次执行时间为1分钟左右,刷新执行,时间为0.00第二次直接取的缓存的了,所以0.00
    打印出
    explain select s,count(s) as c from c group by s order by c desc limit 50;
    看看。
      

  7.   

    分表也一样,你的查询语句中并没有WHERE了句,所以无论如何都是全表数据扫描。
      

  8.   

    您可以使用汇总表,定期将统计数据放进去,查询的时候检索汇总表就可以了(这种方法有点误差,不是适时的)
    假设您的缓存表是s_c`s` varchar(1000) default '',//受访页面
    `c` INT( 11 ) NULL DEFAULT '0',//页面数量然后定期执行
    create table s_c_tmp select s,count(s) as c from c group by s order by c desc;
    drop table if exists s_c_20101110;
    rename s_c_tmp to s_c_20101110;
      

  9.   

    rename table s_c_tmp to s_c_20101110;
      

  10.   

    回楼主,explain是mysql的一个命令,用于显示执行计划的
    mysql的查询性能是依赖于索引的,因此需要给s字段建索引。
    按照你的数量级,建议每天生成一张新表
    速度还不行的话,对`s` varchar(1000) default '',//受访页面进行hash,数据库中保存一个hash int值,这样速度会更快
      

  11.   

    1.定时生成汇总表
    2.不要用数据库存储这些信息,改用文本存储,或者直接分析日志后,将汇总数据存入到数据库
    3.改用分布式存储,比如hadoop或者monodb