1. 程式人生 > >mysql limit 分頁資料丟失問題測試

mysql limit 分頁資料丟失問題測試

背景

前幾天看到有說mysql使用 limit 0,10 這種方式分頁會丟失資料,有人質疑說不會,動手驗證一下。

操作步驟

表結構如下:

create table `test`.`t_model`(  
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
  `uid` bigint COMMENT '業務主鍵',
  `modelid` varchar(50) COMMENT '字元主鍵',
  `modelname` varchar(50) COMMENT '名稱',
  `desc` varchar(50) COMMENT '描述'
, primary key (`id`), UNIQUE index `uid_unique` (`uid`), key `modelid_index` (`modelid`) USING BTREE ) ENGINE=InnoDB charset=utf8 collate=utf8_bin;

構造測試資料語法如下:

drop procedure IF EXISTS u_head_and_low_pro;

delimiter $$
create procedure u_head_and_low_pro()
begin
  DECLARE n int DEFAULT 1;
  set
@exesql = 'insert into t_model (uid,modelid,modelname,`desc`) values '; set @exedata = ''; WHILE n < 10001 DO set @exedata = concat(@exedata,"(",n,",","'id20170831",n,"','","name",n,"','","desc'",")"); if n % 1000 = 0 then set @exesql = concat(@exesql,@exedata,";"); prepare stmt from
@exesql; execute stmt; DEALLOCATE prepare stmt; commit; set @exesql = 'insert into t_model (uid,modelid,modelname,`desc`) values '; set @exedata = ""; else set @exedata = concat(@exedata,','); end if; set n = n + 1; END WHILE; end;$$ delimiter ;

查詢語法如下:

-- 第一頁
select * from t_model limit 0, 10;

-- 第二頁
select * from t_model limit 10, 10;

-- 第三頁
select * from t_model limit 20, 10;

-- 第四頁
select * from t_model limit 30, 10;

-- 第五頁
select * from t_model limit 40, 10;

在查詢時,第一頁是1~10,第二頁是11~20,第四頁時,查詢結果為:
id uid modelid modelname desc


31      31  id2017083131  name31     desc    
32      32  id2017083132  name32     desc    
33      33  id2017083133  name33     desc    
34      34  id2017083134  name34     desc    
35      35  id2017083135  name35     desc    
36      36  id2017083136  name36     desc    
37      37  id2017083137  name37     desc    
38      38  id2017083138  name38     desc    
39      39  id2017083139  name39     desc    
40      40  id2017083140  name40     desc  

此時,查詢第5頁應該是 41~50。如果某人A在介面上查詢資料,現在查詢到第4頁,在顯示完第4頁資料後,另外一個人B(或程式)將第11~20的資料刪除掉了,A再翻頁到第5頁時,此時資料為:
id uid modelid modelname desc


51      51  id2017083151  name51     desc    
52      52  id2017083152  name52     desc    
53      53  id2017083153  name53     desc    
54      54  id2017083154  name54     desc    
55      55  id2017083155  name55     desc    
56      56  id2017083156  name56     desc    
57      57  id2017083157  name57     desc    
58      58  id2017083158  name58     desc    
59      59  id2017083159  name59     desc    
60      60  id2017083160  name60     desc   

也就是說,A在本次操作過程中,如果一直往下翻頁到最後一頁的話,41~50 這頁的資料就無法看到,資料丟失了。
當然,如果重新整理一下介面,重新翻頁就沒有問題了。

結論

如果分頁查詢的表的資料插入和刪除等操作頻繁的話,建議還是使用 limit 10 這種語法方式分頁查詢,可以提升效能,也更準確。