mysql 队列 高并发_Mysql高并发更新

bd96500e110b49cbb3cd949968f18be7.png

I have a mysql table:

CREATE TABLE `coupons` (

`id` INT NOT NULL AUTO_INCREMENT,

`code` VARCHAR(255),

`user_id` INT,

UNIQUE KEY `code_idx` (`code`)

) ENGINE=InnoDB;

The table consists of thousands/millions of codes and initially user_id is NULL for everyone.

Now I have a web application which assigns a unique code to thousands of users visiting the application concurrently. I am not sure what is the correct way to handle this considering very high traffic.

The query I have written is:

UPDATE coupons SET user_id = where user_id is NULL limit 1;

And the application runs this query with say a concurrency of 1000 req/sec.

What I have observed is the entire table gets locked and this is not scaling well.

What should I do?

Thanks.

解决方案

This question might be more suitable for DBA's (and I'm not a DBA) but I'll try to give you some ideas of what's going on.

InnoDB does not actually lock the whole table when you perform you update query. What it does is the next: it puts a record lock which prevents any other transaction from inserting, updating, or deleting rows where the value of coupons.user_id is NULL.

With your query you have at the moment(which depends on user_id to be NULL), you cannot have concurrency because your transaction will run one after another, not in parallel.

Even an index on your coupons.user_id won't help, because when putting the lock InnoDB create a shadow index for you if you don't have one. The outcome would be the same.

So, if you want to increase your throughput, there are two options I can think of:

Assign a user to a coupon in async mode. Put all assignment request in a queue then process the queue in background. Might not be suitable for your business rules.

Decrease the number of locked records. The idea here is to lock as less records as possible while performing an update. To achieve this you can add one or more indexed columns to your table, then use the index in your WHERE clause of Update query.

An example of column is a product_id, or a category, maybe a user location(country, zip).

then your query will look something like this:

UPDATE coupons SET user_id = WHERE product_id = user_id is NULL LIMIT 1;

And now InnoDB will lock only records with product_id = . this way you you'll have concurrency.

Hope this helps!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值