https://mp.weixin.qq.com/s/WsQZhZhuzfs2YZgamrGUOw
大量数据的update和delete操作可采取分批处理。
业务描述:更新用户所有已过期的优惠券为不可用状态。
SQL语句:
update status=0 FROM `coupon` WHERE expire_date <= #{currentDate} and status=1;
如果大量优惠券需要更新为不可用状态,执行这条SQL可能会堵死其他SQL,分批处理伪代码如下:
int pageNo = 1; int PAGE_SIZE = 100; while(true) { List batchIdList = queryList(‘select id FROM `coupon` WHERE expire_date <= #{currentDate} and status = 1 limit #{(pageNo-1) * PAGE_SIZE},#{PAGE_SIZE}‘); if (CollectionUtils.isEmpty(batchIdList)) { return; } update(‘update status = 0 FROM `coupon` where status = 1 and id in #{batchIdList}‘) pageNo ++; }
like用于模糊查询,举个例子(field已建立索引):
SELECT column FROM table WHERE field like ‘%keyword%‘;
这个查询未命中索引,换成下面的写法:
SELECT column FROM table WHERE field like ‘keyword%‘;
去除了前面的%查询将会命中索引,但是产品经理一定要前后模糊匹配呢?全文索引fulltext可以尝试一下,但Elasticsearch才是终极武器。
limit用于分页查询时越往后翻性能越差,解决的原则:缩小扫描范围,如下所示:
select * from orders order by id desc limit 100000,10
耗时0.4秒
select * from orders order by id desc limit 1000000,10
耗时5.2秒
先筛选出ID缩小查询范围,写法如下:
select * from orders where id > (select id from orders order by id desc limit 1000000, 1) order by id desc limit 0,10
耗时0.5秒
如果查询条件仅有主键ID,写法如下:
select id from orders where id between 1000000 and 1000010 order by id desc
耗时0.3秒
如果以上方案依然很慢呢?只好用游标了,感兴趣的朋友阅读JDBC使用游标实现分页查询的方法。
使用查询日志代码。查看日志的具体情况
slow_query_log
当这个参数设置为ON,可以搜寻到时间超过慢查询定义的时间(即1S)SQL语句,默认是off关闭的,使用时,需要改为on 打开。
long_query_time
默认是10S,执行后会浏览所有SQL语句,当某些SQL语句执行超过设定时间后,系统会自动的将该条语句记录到日志中。
slow_query_log_file 记录的是慢日志的记录文件
SHOW STATUS LIKE ‘%slow_queries%‘ 查看慢查询状态
Slow_queries 记录的是慢查询数量 当有一条sql执行一次比较慢时,这个vlue就是1 (记录的是本次会话的慢sql条数)
注意:
如何打开慢查询 : SET GLOBAL slow_query_log = ON;
将默认时间改为1S: SET GLOBAL long_query_time = 1;
(设置完需要重新连接数据库,PS:仅在这里改的话,当再次重启数据库服务时,所有设置又会自动恢复成默认值,永久改变需去my.ini中改)
https://www.cnblogs.com/xk920/p/11132038.html
。。。
原文:https://www.cnblogs.com/dingpeng9055/p/11644629.html