• @suxiaohun 分页条件,过大的offse 提供了一种解决方式,可以试一试

  • 测试了一下,总共5w条数据。效果还是很明显的

    
    def test1
      client = Mysql2::Client.new(:host => "localhost",
                                :username => "root",
                                :password => "",
                                :database => "happy_for_ni"
                                )
      result = client.query('SELECT * FROM videos', :stream => true)
      result.each do |row|
        p row
      end
    end
    
    def test2
      Videos.find_each do |row|
        p row
      end
    end
    
    Benchmark.bm do |x|
    
      x.report {  test2 }
      x.report {  test1 }
    
    end
    
    
    [#<Benchmark::Tms:0x0000010cdc9788 @cstime=0.0, @cutime=0.0, @label="", @real=18.736821, @stime=0.8600000000000003, @total=11.649999999999999, @utime=10.79>,
    #<Benchmark::Tms:0x000001084c0d70 @cstime=0.0, @cutime=0.0, @label="", @real=14.197525, @stime=0.79, @total=6.850000000000002, @utime=6.060000000000002>] 
    
    
    
    
  • RubyConf China 2015 资源汇总 at 2015年10月12日

    👍

  • 语言仅仅是个工具而已,重要的是使用这个语言的人。

  • @jerrym 60W的数据一点都不多,我们的表经常是上百万,千万的,合适的表结构,恰当的索引,都会大大减少查询的时间。

  • @MrPasserby 产品是开发的死对头。一般遇到这种问题,都会详细的了解需求,确定是否要该表结构。 一般遇到这种频繁修改表结构的需求,至少都会在我这边自动屏蔽。

    SO,一个好的产品,很关键。

  • 1、在设计之初,考虑数据增长趋势,建立合适的索引。 2、表关联的外键建立索引。 3、建立一些冗余数据,来避免join查询

    @peter 所说的一样

    比如两个表 deals(tb_shop_id) 和 tb_shops(wangwang, name.....) 。经常有这种需求,根据 wangwang 去查询deals 数据 一般写法

    SELECT deals.*
    FROM deals INNER JOIN tb_shops ON deals.tb_shop_id = tb_shops.id
    WHERE tb_shops.wangwang='xxxxxx'
    

    但是,如果在设计之初,考虑到这种需求,那么在表 deals上记录 tb_shop_id 和 wangwang,那么就不需要join 表查询了。 只有在 tb_shops.wangwang 修改的时候同步 deals 表 如下:

    SELECT deals.*
    FROM deals 
    WHERE deals.wangwang = 'xxxxxx'
    

    4、数据库良好的设计,一定要,所见及所得,避免复杂的查询。 比如日志表,xxxx_logs 可能会有百万或千万的数据。那么避免对这个表做任何查询。可以根据需求建立几个小的统计表。 比如,商家每天的消费情况,商家的总消费情况,所有的数据在存入 xxxx_logs 的时候,对应把数据同步到这几个小表中。

    商家每日消费情况表tb_shop_day_details,商家总消费情况tb_shops_total_details

    比如查看所有商家的总消费情况,只需要查询 tb_shops_total_details 不再需要从 xxxx_logs 临时计算数据,返回。 比如,要查看商家2014-11-11那一天消费的情况,那么也只需要

    SELECT *
    FROM tb_shop_day_details
    WHERE st_date = '2014-11-11'
    

    所有数据所见及所得,那么这种情况就不需要JOIN表操作。

    5、将多表的数据查询,提前汇总到一个表。在真正需要查询的时候,从该汇总表中查询。

    6、读写分离。在主库写,从库读。

    7、将多表join 查询,改成几条简单的SQL查询,最后在组合数据。

    8、如果觉得上述的太麻烦,使用solr吧,但是原理是一样的,将预计要查询的汇总在一个表。

    其实多表查询慢,第一、没有建立合适的索引,第二,存在不良的表结构设计。 在系统初期,没有做好设计。导致数据增长不可控,不良的表结构设计,肯定会导致多表查询慢。 要解决多表查询缓慢的问题,从修改表结构开始,一步一步优化,肯定能达到预期的效果。

  • @hbin 真真的 -:

  • 使用ID 最好。

    不过在做这个API之前,验证请求的访问者。

    不建议使用A-1这种方式,这种情况加大了程序的复杂度。违背单一职责原则。如果PC,无线,其他平台都需要使用你这个接口,那么是不是,这几个平台都需要重写一下解析A-1这段代码呢?

    本来很简单的东西,考虑的情况太多,反而影响自己的判断。不论任何设计,都应该以简单松耦合单一可扩展为基础准则。

  • 直接操作redis,就能实现共享。写入redis 的数据,消息队列就可以直接消耗了呢。

    给你个例子参考下

    1、使用 redis 左入队列(lpush)的方式,插入数据

    插入队列的名字: zzzz:queue:cpc_for_deals

    Redis.current.lpush("zzzz:queue:cpc_for_deals", example_record.to_json)

    务必为左入队列!!!

    2、具体数据格式如下

    example_record = { :retry=>5, :queue=>"cpc_for_deals", :class => "CpcLogsWorker", :args => [deal_id, added_count], :jid => "4f54290c1224e44007a02f49", :enqueued_at => 1427009697.350305 }

    其中:

    • retry 表示 重试次数

    • queque 表示 入哪个队列

    • class 表示 sidekiq 处理的Worker 的名字

    • args 表示 需要处理的数据。第一个参数为deal_id , 第二个参数为 该deal 增加的点击数

    • jid 表示 24 位唯一随机数 Ruby 使用 SecureRandom.hex(12) 实现

    • enqueued_at 表示 从 1970.01.01 00:00:00 到现在的毫秒数, 注意是带小数点的
      Ruby 中的表示方式为 Time.now.to_f

    Redis.current.lpush("zzzz:queue:cpc_for_deals", example_record.to_json)