算法目的:分批处理A表全部记录,并每条记录只处理一次。已知条件:
1,数据库为mysql。
2,处理中A表中的记录不会被其他程序增加或修改或删除。即A表为固定表。
3,A表有唯一主键,并不存在其他索引。算法顺序:
1,select * from A limit 1000 offset 0;得到x条记录并进行处理。
2, if (x < 1000) 认为全部记录已经被处理完毕。
   else 重复顺序1(其中offset = offset + 1000)乍看上去好像没有什么问题,但是我觉得上述算法存在的问题:
把算法顺序1中的SQL文改成select * from A order by pk limit 1000 offset 0,就严谨了,但是order by pk(pk为主键)一加上去,就付出了using temporary和using filesort的代价。放到谁都很不愿意加order by,但是有没有理论支持可以不加order by啊?

解决方案 »

  1.   

    的确不加ORDER BY的关不严谨。但不确定你的主键是不是你所说的。贴出你的 show create table A; show index from A; explain select * from A order by pk limit 1000 offset 0;这样别人就不需要凭空猜测了,
      

  2.   

    A表要是固定表的话,不会被删除,插入顺序一样的话,,加order by id 来排序和不加order by id 排序结果应该是一样的.
      

  3.   

    order by pk 没理由用临时表排序啊 本来就是排序的
      

  4.   

    对不起大家,是我的题目错了。如果是题目中的条件的话,加不加order by pk,explain的结果都是一样的。
    比如下表
    CREATE TABLE `temp_rcfc` (
    `RCFC_KBN` CHAR(3) NOT NULL,
    `RCFC_NM` CHAR(30) NOT NULL,
    PRIMARY KEY (`RCFC_KBN`)
    )
    ENGINE=InnoDB
    ROW_FORMAT=DEFAULTexplain select * from TEMP_RCFC r order by r.RCFC_KBN limit 1000 offset 0;
    和explain select * from TEMP_RCFC r limit 1000 offset 0;
    都不会出现using temporary或者using filesort。如果是父子表的话,通过join查询的话,加不加order by pk就会差很大。
    比如:select * from TBL_NODE n, TBL_SHOP s where n.NODE_ID = s.NODE_ID and n.VALID=1 order by n.NODE_ID  limit 1000 offset 0; 其中TBL_NODE是父表,TBL_SHOP是子表,两表通过NODE_ID主键来表示同一对象。这个时候有没有好一点的解决方法啊
      

  5.   

    n.VALID,n.NODE_ID,n.NODE_ID 加上联合索引和s.NODE_ID加上索引 看看;
    楼主最好不要select * ,把需要的字段列出来;
      

  6.   

    谢谢,s.NODE_ID是SHOP表的主键了,应该不需要加索引了吧。还有关于NODE表的索引最好不希望添加,就NODE_ID为主键就好了,而n.VALID是0或者1的有效无效位。在这种情况下,要分批处理SHOP表中的所有记录(无效SHOP除外),有没有什么好方法。
      

  7.   

    没有索引join 查询的话,当然差的很大了.
      

  8.   

    我觉得您没有理解我的意思。现在的问题不是n.VALID的问题,而是group by加或不加所导致的差别。那我现在把VALID去掉,把SQL简化成select * from TBL_NODE n, TBL_SHOP s where n.NODE_ID = s.NODE_ID  order by n.NODE_ID limit 1000 offset 0;这个时候加order by与不加order by在explain下会有using temprary和using filesort,但是实际运算的结果却没有差,因此我想不加order by,但苦于没有理论依据。
      

  9.   

    这个时候加order by与不加order by在explain下会有using temprary和using filesort,
    都有?还是不加有?
      

  10.   

    注意以下几点!1. 你用的INNODB存储引擎,INNODB使用的是主键聚集索引。
    2. 你的SELECT不包括任何WHERE条件,所以是全表扫描因此 不会使用,也没有必要使用索引。 因为INNODB的 聚集索引 会导致 输出会按 主键的顺序输出。但仍然保持程序的严谨,把ORDER BY加上。
      

  11.   

    这个论坛没有办法一个回复同时两个引用啊。回9楼,不加order by的话,using temprary和using filesort都没有,加了order by的话,using temprary和using filesort都有。
      

  12.   

    using filesort :是没有利用到索引而进行排序;想取消必须要利用索引;
    using temprary :是需要一张临时表来;
    加不加order by 没有差 我觉得不可能,除非数据量很少,或则order by 利用了索引;楼主order by 主键,我觉得差距不大,不是没有差;