首页
关于
Search
1
联想510s mini 安装 Ventura
898 阅读
2
基于K8s + Jenkins+Docker + Gitee 自动部署 - 配置 Jenkins Item + Gitee Webhook (二)
568 阅读
3
Spring Boot Schedule疑问及线程池配置
467 阅读
4
Server Send Events With Spring Boot
410 阅读
5
Ngrok使用自有服务器服务器及域名 - 解决Mac client问题
389 阅读
默认分类
SSH
typecho
Spring boot
其他
mysql
k8s
jenkins
docker
Java
mqtt
MongoDB
登录
/
注册
Search
标签搜索
k8s
docker
ssh
mysql
db
gitee
jenkins
ngrok
黑苹果
MQTT
CC
累计撰写
19
篇文章
累计收到
0
条评论
首页
栏目
默认分类
SSH
typecho
Spring boot
其他
mysql
k8s
jenkins
docker
Java
mqtt
MongoDB
页面
关于
搜索到
1
篇与
db
的结果
2022-05-13
记一次Mysql优化
优化一:批量插入 (实际业务中,耗时从400s左右降到7s左右)伪代码 @Cleanup Connection conn = DaoUtils.getConnection(false); String sql = "INSERT INTO xx (column1, column2) VALUES (?, ?)"; PreparedStatement ps = conn.prepareStatement(sql); for (int i = 0; i < 1000000; i++) { ps.setString(1,"column1"); ps.setString(2,"column2"); ps.addBatch(); // 每1000条记录插入一次 if (i % 1000 == 0) { ps.executeBatch(); conn.commit(); ps.clearBatch(); } } // 剩余数量不足1000 ps.executeBatch(); conn.commit(); ps.clearBatch();默认情况下,有多少条数据,就会执行多少条sql。可以在mysql链接加上rewriteBatchedStatements=true,将多条插入sql重写为1条,可以有效减少sql执行次数。按照上面的代码,执行sql条数为执行executeBatch的次数。jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true 官方文档:rewriteBatchedStatements Should the driver use multi-queries (regardless of the setting of "allowMultiQueries") as well as rewriting of prepared statements for INSERT into multi-value inserts when executeBatch() is called? Notice that this has the potential for SQL injection if using plain java.sql.Statements and your code doesn't sanitize input correctly. Notice that for prepared statements, server-side prepared statements can not currently take advantage of this rewrite option, and that if you don't specify stream lengths when using PreparedStatement.set*Stream(), the driver won't be able to determine the optimum number of parameters per batch and you might receive an error from the driver that the resultant packet is too large. Statement.getGeneratedKeys() for these rewritten statements only works when the entire batch includes INSERT statements. Please be aware using rewriteBatchedStatements=true with INSERT .. ON DUPLICATE KEY UPDATE that for rewritten statement server returns only one value as sum of all affected (or found) rows in batch and it isn't possible to map it correctly to initial statements; in this case driver returns 0 as a result of each batch statement if total count was 0, and the Statement.SUCCESS_NO_INFO as a result of each batch statement if total count was > 0. Default Value false Since Version 3.1.13 https://dev.mysql.com/doc/connectors/en/connector-j-connp-props-performance-extensions.html优化二:添加索引(分析sql,扫描数量、索引命中情况)表结构mysql> desc detection_plains; +-------------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | .. | ....... | NO | | NULL | | | peopleId | bigint(20) | NO | | NULL | | | plainType | int(2) | NO | | 0 | | +-------------------+--------------+------+-----+---------+----------------+ xx rows in set (0.02 sec)已有索引 mysql> show index from t_name; +------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | t_name | 0 | PRIMARY | 1 | id | A | 169267 | NULL | NULL | | BTREE | | | +------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 1 row in set (0.00 sec)这张表目前仅有主键 查询sql mysql> select no from t_name where peopleId=9379 and plainType=1 order by schedule DESC limit 1; +----+ | no | +----+ | 10 | +----+ 1 row in set (2.23 sec)这里花了2s+,不太符合预期explain:查询执行sql情况,扫了多少条数据、有没有使用索引mysql> explain select no from t_name where peopleId=9379 and plainType=1 order by schedule DESC limit 1; +----+-------------+------------------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+ | 1 | SIMPLE | detection_plains | NULL | ALL | NULL | NULL | NULL | NULL | 169301 | 1.00 | Using where; Using filesort | +----+-------------+------------------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+ 1 row in set, 1 warning (0.00 sec) 目前表数据量 mysql> select count(id) from t_name; +-----------+ | count(id) | +-----------+ | 175575 | +-----------+ 1 row in set (5.45 sec) 通过explain结果看,目前查询sql并未使用索引,几乎扫了整张表的数据。我们在peopleId,plainType列添加索引mysql> alter table t_name add index peopleIdPlainType(`peopleId`,`plainType`); Query OK, 0 rows affected (8.29 sec) Records: 0 Duplicates: 0 Warnings: 0 再次explain可知,扫描数据下降到10条,命中了创建的peopleIdPlainType的索引。 mysql> explain select no from t_name where peopleId=9379 and plainType=1 order by schedule DESC limit 1; +----+-------------+------------------+------------+------+-------------------+-------------------+---------+-------------+------+----------+---------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------------+------------+------+-------------------+-------------------+---------+-------------+------+----------+---------------------------------------+ | 1 | SIMPLE | detection_plains | NULL | ref | peopleIdPlainType | peopleIdPlainType | 12 | const,const | 10 | 100.00 | Using index condition; Using filesort | +----+-------------+------------------+------------+------+-------------------+-------------------+---------+-------------+------+----------+---------------------------------------+ 1 row in set, 1 warning (0.01 sec) mysql> select no from t_name where peopleId=9379 and plainType=1 order by schedule DESC limit 1; +----+ | no | +----+ | 10 | +----+ 1 row in set (0.00 sec) mysql> show profiles; +----------+------------+------------------------------------------------------------------------------------------------------------------+ | Query_ID | Duration | Query | +----------+------------+------------------------------------------------------------------------------------------------------------------+ | 3 | 0.00723975 | select no from t_name where peopleId=9379 and plainType=1 order by schedule DESC limit 1 | +----------+------------+------------------------------------------------------------------------------------------------------------------+ 3 rows in set, 1 warning (0.00 sec) 查询时间从2s+降到了7ms左右其他不使用“大事务":如果执行操作耗时高且开启了事务,容易导致Lock wait timeout exceeded; try restarting transaction 异常使用SELECT * FROM information_schema.INNODB_TRX;可查询当前事务数量、执行状态和执行的sql等信息尽量不并行操作db,会增加单个事务耗时
2022年05月13日
150 阅读
0 评论
0 点赞