测试循环执行一个update sql,效率非常差,不知道是不是锁住了整个表

MySql 码拜 10年前 (2014-04-27) 1424次浏览 0个评论
 

sql如下:

UPDATE t_access_token SET state = 1 
WHERE state = 0 
AND account = ""账号,每条sql值都不一样"" 
AND token <> ""令牌,每条sql值都不一样"";

仅仅是测试2000个线程,每个线程才跑一遍,效率都非常差,平均每个线程差不多要10秒。
表总共40W条数据,但每条sql有更新到的也就一两条记录,表结构有以下字段:id,state,account,token,createTime。
是不是mysql没有用行锁,而是用了表锁?

10分
是不是  where  的字段没有索引
引用 1 楼 yuhaiyang457288 的回复:

是不是  where  的字段没有索引

有的,where的三个字段都分别加上了索引

20分
贴出 explain select * from t_access_token WHERE?state?=?0?
AND?account?=?””账号,每条sql值都不一样””?
AND?token?<>?””令牌,每条sql值都不一样””;

的结果以供分析。

20分
1.看一下存储引擎是否为myisam。如果是myisam则改为innodb。
   show create table t_access_token;
   如果是myisam则修改为innodb:   alter table t_access_token engine=innodb;
2.看一下执行计划,并贴出结果。
   explain select * from t_access_token where state=0 and account=””xxx”” and token <> “”xxx””;
引用 3 楼 ACMAIN_CHM 的回复:

贴出 explain select * from t_access_token WHERE?state?=?0?
AND?account?=?””账号,每条sql值都不一样””?
AND?token?<>?””令牌,每条sql值都不一样””;

的结果以供分析。

引用 4 楼 chenhuayun 的回复:

1.看一下存储引擎是否为myisam。如果是myisam则改为innodb。
   show create table t_access_token;
   如果是myisam则修改为innodb:   alter table t_access_token engine=innodb;
2.看一下执行计划,并贴出结果。
   explain select * from t_access_token where state=0 and account=””xxx”” and token <> “”xxx””;

谢谢回答,表是Innodb引擎
结果如下

id  select_type  table           type         possible_keys                                                        key                                            key_len  ref  rows  Extra                                                                        
1   SIMPLE       t_access_token  index_merge  idx_accesstoken_token,idx_accesstoken_state,idx_accesstoken_account  idx_accesstoken_state,idx_accesstoken_account  4,66          523   Using intersect(idx_accesstoken_state,idx_accesstoken_account); Using where  
10分
索引没有创建。
create index sss on t_access_token(state,account,token);
10分
引用 6 楼 ACMAIN_CHM 的回复:

索引没有创建。
create index sss on t_access_token(state,account,token);

个人意见:如果索引这样建立,猜测表中state字段=0的数据应该占表中总数据大于10%
                   所以我认为可以create index sss on t_access_token(account,token,state);
楼主可以随意变换下位置测试下。
谢谢

引用 6 楼 ACMAIN_CHM 的回复:

索引没有创建。
create index sss on t_access_token(state,account,token);

是分成三个索引来建的,合起来就不会有问题了吗

引用 7 楼 u011575570 的回复:
Quote: 引用 6 楼 ACMAIN_CHM 的回复:

索引没有创建。
create index sss on t_access_token(state,account,token);

个人意见:如果索引这样建立,猜测表中state字段=0的数据应该占表中总数据大于10%
                   所以我认为可以create index sss on t_access_token(account,token,state);
楼主可以随意变换下位置测试下。
谢谢

好的,我明天合起来测下

10分
引用 1 楼 yuhaiyang457288 的回复:

是不是  where  的字段没有索引

引用 1 楼 yuhaiyang457288 的回复:

是不是  where  的字段没有索引

应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。  

10分
引用 1 楼 yuhaiyang457288 的回复:

是不是  where  的字段没有索引

引用 2 楼 linminqin 的回复:
Quote: 引用 1 楼 yuhaiyang457288 的回复:

是不是  where  的字段没有索引

有的,where的三个字段都分别加上了索引

应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。  

引用 11 楼 yuhaiyang457288 的回复:
Quote: 引用 1 楼 yuhaiyang457288 的回复:

是不是  where  的字段没有索引

引用 2 楼 linminqin 的回复:
Quote: 引用 1 楼 yuhaiyang457288 的回复:

是不是  where  的字段没有索引

有的,where的三个字段都分别加上了索引

应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。  

明白了,但是像我这条需要过滤的语句,如果不用<>,要怎么写

10分
引用 12 楼 linminqin 的回复:
Quote: 引用 11 楼 yuhaiyang457288 的回复:
Quote: 引用 1 楼 yuhaiyang457288 的回复:

是不是  where  的字段没有索引

引用 2 楼 linminqin 的回复:
Quote: 引用 1 楼 yuhaiyang457288 的回复:

是不是  where  的字段没有索引

有的,where的三个字段都分别加上了索引

应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。  

明白了,但是像我这条需要过滤的语句,如果不用<>,要怎么写

看看把前两者建立一个索引,最后哪个单独建一个索引。这个不敢肯定呀。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明测试循环执行一个update sql,效率非常差,不知道是不是锁住了整个表
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!