表A,start_ip,end_ip
表B,login_ipselect start_ip,end_ip,(select count(*) from B where login_ip bewteen start_ip and end_ip) numbers from A
这条语句的意思是求出每条start_ip,end_ip,numbers(这个IP区间内的登录数量)这条语句在mysql数据库中执行非常非常慢,有什么办法可以优化吗?本人已经对B表的login_ip做了MYISAM索引。

解决方案 »

  1.   

    try:
    select a.start_ip,a.end_ip,
    sum(if(b.login_ip between a.start_ip and a.end_ip,1,0))
     from a,b 
    group by a.start_ip,a.end_ipor
      

  2.   

    select start_ip,end_ip,count(*) from a ,b   where b.login_ip between start_ip and end_ip  group by start_ip,end_ip ;
      

  3.   


    1.alter table a add index ipindex on (start_ip,end_ip)
    2.select a.start_ip,a.end_ip,count(distinct b.login_ip) from a inner join b on b.login_ip between a.start_ip and a.startip -- 或者用left (b.login_ip,8)=left(a.start_ip,8) 这样做是为了保证合理利用索引。不知道between and 会不会把varchar类型转换
    group by a.start_ip,a.end_ip
    还有一种思路是新建ip起始终止字段为整型把ip 转为256进制 如192.168.0.255 转换为192*256^3+168*256^2+0*256^1+1*256^0形式。
    在起始终止ip上建索引。
    同理为login_ip建立转256形式函数或单建256形式字段,进行联接就会快了。
      

  4.   

    先用3楼的方法,在 表B,login_ip 加索引。然后
    select start_ip,end_ip,count(*)
    from a inner join b on a.start_ip<=b.login_ip and a.end_ip>=b.login_ip
    group by start_ip,end_ip;不过对要看你的表是数据格式,估计是不行
    要对你IP地址要用函数处理一下才行。
    172.0.0.1 - 172.1.255.255
    172.1.13.134
    纯用字符串比较是不行了。用instr,substr等函数处理一下。
    具体函数的用法,你可以查手册,比较简单我就不帮你写了。
    .
        [align=center]====  ====
    [/align]
    .
    贴子分数<20:对自已的问题不予重视。
    贴子大量未结:对别人的回答不予尊重。
    .
      

  5.   

    用inet_aton()可以将ip从字符串转为int unsigned,这样效率会提高一些。我之前也碰到过ip匹配在beg和end之间效率慢的问题,暂时没想到什么好方法。因为这样的索引几乎不起效果,琢磨了一个偏门的方法,在beg,end之外再增加一个前8位是什么的列,这样先比较前8为是否相同(A类地址),再看是否属于beg,end的区间内。
    -- 
    http://www.xiaochn.cn/
    人生就像冰箱,装满是为了掏空,而不是保存
    ----------------------------------------
    http://shop35711789.taobao.com/
    提供新西兰特产、世界顶级蜂蜜,各位朋友常来看看 
      

  6.   

    人生就像冰箱,装满是为了掏空,而不是保存
    ----------------------------------------
    http://shop35711789.taobao.com/
    提供新西兰特产、世界顶级蜂蜜,各位朋友常来看看  是不是免费提供?.
        [align=center]====  ====
    [/align]
    .
    贴子分数<20:对自已的问题不予重视。
    贴子大量未结:对别人的回答不予尊重。
    .
      

  7.   

    B表有上亿条记录,用我的SQL语句,1分40秒应该可以接受这个速度