本帖最后由 ecshop528 于 2012-10-11 11:32:16 编辑

解决方案 »

  1.   

    建立联合索引 alter table xxx add index(is_delete,is_real,goods_i)
      

  2.   

    explain SELECT goods_id, goods_name, goods_type, goods_sn, shop_price, is_on_sale, is_best, is_new, is_hot, sort_order, goods_number, integral, (promote_price > 0 AND promote_start_date <= '1349942399' AND promote_end_date >= '1349942399') AS is_promote FROM `icmall`.`ecs_goods` AS g WHERE is_delete='0' AND is_real='1' ORDER BY goods_id DESC LIMIT 2111111,20
    1 SIMPLE g ref delete_real_goods_id delete_real_goods_id 2 const,const 2302639 Using where
      

  3.   

     LIMIT 2111111,20 MySQL会扫描2111111+20条记录,然后丢掉2111111条记录,基本上把全表扫描完了。所以会很慢。
    你有没有可能获得上一页的id,通过id>的方式来处理分页?否则有这么多IO,时间耗费肯定会比较高的
      

  4.   

    LIMIT 2111111,20 偏移量一大, 即使有索引, 也是一样慢的, 索引是用来match值的, 如果是用来顺序扫描,也是很慢的.
    还是用6楼的方法吧, 改表一下思路吧.
      

  5.   


    能写个大概的SQL语句做个参考吗。呵呵。谢谢
      

  6.   

    支持6楼,这两个字段只有0和1,选择性低,用索引相当于全表扫描select .....  from `icmall`.`ecs_goods`  AS g join 
    (select goods_id FROM `icmall`.`ecs_goods`  WHERE is_delete='0' AND is_real='1' ORDER BY goods_id DESC LIMIT 2111111,20
    ) as t using (goods_id)