从一个表中随机提取10条数,并标记这10条记录已经被提取过。怎么做呢?怎么样做效率高呢,谢谢!!!

解决方案 »

  1.   

    mysql> select * from t1 order by rand() limit 10;
    +-------+-------+
    | id    | col   |
    +-------+-------+
    | 66104 | 66104 |
    | 33227 | 33227 |
    | 85053 | 85053 |
    | 62135 | 62135 |
    | 80887 | 80887 |
    | 87671 | 87671 |
    | 24325 | 24325 |
    | 57971 | 57971 |
    | 50360 | 50360 |
    | 19033 | 19033 |
    +-------+-------+
    10 rows in set (0.30 sec)mysql>并标记这10条记录已经被提取过
    需要按照提取的结果,再更新回原表。没有什么特别的办法,只能通过程序来实现。
      

  2.   

    ACMAIN_CHM 我是多个线程同时跑,要保证每条数据只被读取一次?一次要读取10条,并标记这10条记录已经被读取过了。不能用程序啊。如果用程序的话。还没来得及更新,其它线程可能已经读取这些数据了。就是要问怎么处理中间结果呢?
    1、 select * from t1 where t1.flag=0 order by rand() limit 10 for update;
    update t1 set t1.flag=1 ...后边怎么写呢?
    谢谢!
      

  3.   

    多线程并发,比较麻烦。
    只能用LOCK了。你用的什么存储引擎?
      

  4.   

    innodb
    这样就好!你可以用事务。在事务中, 你可以先   select * from t1 order by rand() limit 10 for update;
    然后再把这 10 条记录的ID得到后再  update t1 set flag=1 where id in (66104 ,33227 ,85053 ,...)
      

  5.   

    start transaction;
    1,select * from t1 order by rand() limit 10 for update; 
    2,这怎么写呢 如何得到 (66104 ,33227 ,85053 ,...),
    3,update t1 set flag=1 where id in (66104 ,33227 ,85053 ,...);
    commit;
    谢谢,
      

  6.   

    start transaction; 
    1,create TEMPORARY TABLE tmp_tbl  select * from t1 order by rand() limit 10 for update; 
    3,update t1 set flag=1 where id in (select id from tmp_tbl);
    4,select * from tmp_tbl;
    commit;这是个意思,但mysql临时其它线程也可见,所以执行是会有问题。第二线程执行时表 tmp_tbl  已经存在了并在使用过程中。如何解决呢?
    谢谢!
      

  7.   


    不能。其它进程 如果 select * from t1 order by rand() limit 10 for update;  恰巧与这已经锁住的10条有相同的,则必须等待你的事务提交后,再能继续。你可以自己做个试验。
    在一个连接中 select * from t1 order by rand() limit 10 for update;   然后再开一个连接, select * from t1 where id= xxx for update;  随便写个被锁的ID。
      

  8.   

    能帮我写个完整的例子吗?谢谢,
    现在这两种都不行。临时表,其它线程也可见!
    start transaction; 
    1,create TEMPORARY TABLE tmp_tbl  select * from t1 order by rand() limit 10 for update; 
    3,update t1 set flag=1 where id in (select id from tmp_tbl); 
    4,select * from tmp_tbl; 
    commit; start transaction; 
    1,create TEMPORARY TABLE tmp_tbl  select * from t1 order by rand() limit 10 for update; 
    3,update t1 inner join tmp_tbl   on t1.id=tmp_tbl.id set flag=1 ;
    4,select * from tmp_tbl; 
    commit; 
      

  9.   

    你用什么语言开发?直接在你的 C 或者 java 中实现。
      

  10.   

    我用 .net C#。如何做呢。谢谢
      

  11.   

    这个建议你到C#的版块去问一下。1. C#中打开事务。
    2。C#中利用ADO。NET得到这个 select * from t1 order by rand() limit 10 for update; 
    3. C# 根据得到的记录集,生成这个   (66104 ,33227 ,85053 ,...); 字符串。
    4。 C#执行 update t1 set flag=1 where id in (66104 ,33227 ,85053 ,...);
    5. C# 中commit; 事务
    如果上述哪一个你不会,建议你到C#去问一下。
      

  12.   

    我只想通过一个存储过程来实现。不想在程序中做。ado中开启事务,我觉得效率低!谢谢你的回复。
      

  13.   

    如果你的问题的标题是: 用存储过程来实现。则可以如下。declare v_xxx varchar(1000);
    START TRANSACTION;
    select group_concat(id) into v_xxx from (select id from t2 where falg=0 order by rand() limit 10 for update) t;
    update t2 set flag=1 where find_in_set(id,@xxx);
    commit;
    select * from t2 where find_in_set(id,@xxx);
      

  14.   

    我用的UuiD做主键,这样查询的结果怎么不对呢。start transaction;select group_concat(  id ) into @v from tb1 limit 10 for update;
    select * from tb1 where find_in_setid,@v); 
    commit;
    得到了27条记录·奇怪呢??
      

  15.   

    不要用 SESSIO变量@v  
    用 局部变量v_xxx 
      

  16.   

    我最终这样做。看看有没有什么问题!
    start trnasaction;
    set @selectid=uuid();
    update t1 a inner join(select id from t1 where t1.flag=0 limit 10 for update) b on a.id=b.id set a.flag=1,a.selectid=@selectid;
    select * from t1 where  flag=1 and selectid==@selectid;
    commit;
    直接更新符合条件的记录。利用 uuid()的唯一性来获取记录。这样在多线程并发时应该不会有问题了。不过不知道效率如何?
    明白人给指点一下。谢谢!
      

  17.   

    效率要测试一下,要在flag、selectid 上建立复合索引
      

  18.   

    declare v_xxx varchar(1000);
    START TRANSACTION;
    select group_concat(id) into v_xxx from (select id from t2 where falg=0 order by rand() limit 10 for update) t;
    update t2 set flag=1 where find_in_set(id,v_xxx );
    commit;
    select * from t2 where find_in_set(id,v_xxx );
    可以试一下这个。
    你的多个线程共享的一个连接。