SQL调优怎么生成海量测试数据
admin
2023-05-23 22:23:17
0

场景,如果出现慢SQL,需要DBA加索引优化,怎么知道加的索引是有效的呢?这需要一遍遍的试验和调整,总不能直接拿线上的数据库测试吧,一般方法是在测试环境建立测试表,然后从线上的从库拷贝一些数据进测试环境,接着再进行加索引和explain

但有时候,导出的数据量少,执行计划看不出效果,导出数据量多,又会冲刷线上机器的buffer pool和影响IO,如果有个工具能够直接生成数据就好了,生成跟线上一样的100万,或者1000万就好了

以前sysbench压力测试,有一个生成数据的功能,生成100万数据是这样的

sysbench --test=oltp --mysql-table-engine=myisam --oltp-table-size=1000000 \
--mysql-socket=/tmp/mysql.sock --mysql-user=test --mysql-host=localhost \
--mysql-password=test prepare

但它生成表结构是固定的,进行压力测试的SQL语句也是固定的,无法调试线上的SQL语句

CREATE TABLE `sbtest` (
 `id` int(10) unsigned NOT NULL auto_increment,
 `k` int(10) unsigned NOT NULL default '0',
 `c` char(120) NOT NULL default '',
 `pad` char(60) NOT NULL default '',
 PRIMARY KEY (`id`),
 KEY `k` (`k`));

能否有一个创建用户自定义的表结构,并且对这个表结构生成上百千万数据的工具呢?有一个叫datagen的工具,链接在文章末尾

drwxr-xr-x. 2 root mysql     4096 Sep 27  2016 bizsql
drwxr-xr-x. 2 root mysql     4096 May 31 20:51 conf
-rw-r--r--. 1 root mysql 23698092 Sep 27  2016 datagen.jar
-rwxr-xr-x. 1 root mysql      147 Sep 27  2016 datagen.sh
-rw-rw-r--. 1 root mysql    31599 May 31 20:54 envbuilder.log
-rw-r--r--. 1 root mysql     1741 May 31 20:53 example.schema
-rw-r--r--. 1 root mysql     1336 May 31 09:42 example.schema_backup
-rw-r--r--. 1 root mysql     2062 Sep 27  2016 readme

方法很简单的2步,把你想要的表结构和想要生成多少条数据,写入到example.schema文件,比如这样,如果想要生成100万条数据,在表末尾加入注释/*{RC{1000000}}*/

CREATE TABLE `test`.`tbl_test` (
`post_id` BIGINT(20) DEFAULT '0'  ,
`star` INTEGER(10) DEFAULT '0'  ,
`view_count` INTEGER(11) DEFAULT '0'  ,
`bean` INTEGER(11) DEFAULT '0'  ,
`nearby` INTEGER(11) DEFAULT '0'  ,
PRIMARY KEY (post_id) ,
INDEX (poster_uid)
) COLLATE='utf8mb4_general_ci' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 /*{RC{1000000}}*/;

第2步,填写连接测试数据库的账号密码,只需要加入一行

vi conf/datagen.xml 

    
        
           
                 
           
           
           
           
           
           
           
        

接着运行shell脚本,往测试库建表,插入数据

[root@localhost datagen]# /bin/bash datagen.sh

[2017-05-31 08:53:15][WARN ] [DataGen :184] - Parsing ddl...
[2017-05-31 08:53:15][WARN ] [DataGen :187] - Creating table...
[2017-05-31 08:53:15][WARN ] [MultiThreadPrepareDataComparator:508] - Preparing generators...
[2017-05-31 08:53:15][WARN ] [MultiThreadPrepareDataComparator:510] - Generating dynamic data...
[2017-05-31 08:54:34][WARN ] [MultiThreadPrepareDataComparator:526] - Generate done.

在测试库,就会出现100万条数据了

mysql> select count(*) from test.tbl_test;
+----------+
| count(*) |
+----------+
|  1000000 |
+----------+
1 row in set (0.16 sec)

现在就可以加索引,explain线上真实的SQL语句了

mysql> explain select post_id  from test.tbl_test where post_type <> 1 and check_status = 9 and flag = 1 and post_time < 1496178301 order by post_time asc limit 200; \G
+----+-------------+----------+-------+---------------+-----------+---------+------+--------+-------------+
| id | select_type | table    | type  | possible_keys | key       | key_len | ref  | rows   | Extra       |
+----+-------------+----------+-------+---------------+-----------+---------+------+--------+-------------+
|  1 | SIMPLE      | tbl_test | range | post_time     | post_time | 9       | NULL | 501491 | Using where |
+----+-------------+----------+-------+---------------+-----------+---------+------+--------+-------------+
1 row in set (0.00 sec)
ERROR: 
No query specified

加索引

mysql>  alter table test.tbl_test add index idx_f(check_status,flag,post_type,post_time);           
Query OK, 0 rows affected (4.45 sec)
Records: 0  Duplicates: 0  Warnings: 0

再来一次explain,扫描50万行变2行

mysql> explain select post_id  from test.tbl_test where post_type <> 1 and check_status = 9 and flag = 1 and post_time < 1496178301 order by post_time asc limit 200; \G
+----+-------------+----------+-------+-----------------+-------+---------+------+------+------------------------------------------+
| id | select_type | table    | type  | possible_keys   | key   | key_len | ref  | rows | Extra                                    |
+----+-------------+----------+-------+-----------------+-------+---------+------+------+------------------------------------------+
|  1 | SIMPLE      | tbl_test | range | post_time,idx_f | idx_f | 15      | NULL |    2 | Using where; Using index; Using filesort |
+----+-------------+----------+-------+-----------------+-------+---------+------+------+------------------------------------------+
1 row in set (0.00 sec)

等调试好索引以后,确定能优化SQL以后,再往线上环境去加索引

当然还有一些很强大的功能

比如某个字段,只出现规定的几个值,比如状态status字段0,1,2,以及每个状态出现的概率

比如模拟线上的用户UID,可以限制某个字段随机数的范围,从00000001到899999999之间等

相关内容

热门资讯

德瑞斯电子取得新型散热风扇专利... 国家知识产权局信息显示,深圳市德瑞斯电子科技有限公司取得一项名为“一种新型散热风扇”的专利,授权公告...
新兴技术及应用产业日报(05.... 公司动态 中国移动段晓东:6G智能体通信——智能经济发展新范式 中国移动研究院副院长段晓东在...
2026年618购机指南:50... 随着618购物节的临近,许多消费者都在寻找一款预算在5000元左右,既能满足日常高强度拍照需求,又无...
体育博物馆如何在互联网时代维持... 上海体育博物馆正在利用更多科技与智能,让游客能够沉浸式逛展。 博物馆如何在当今人工智能盛行的互联网时...
万斯大型失忆现场:呼吁投票反对... 美国副总统JD・万斯近日深陷网络群嘲。他呼吁支持者“投票反对华盛顿疯狂的领导层”,似乎忘了如今是谁在...
原创 在... NASA的气候模拟研究显示:40 亿年前,太阳刚形成不久,亮度只有现在的70%,整个太阳系比现在凉爽...
24岁演员,骑机车意外离世 近日,24岁短剧男演员黄子仟被曝离世,好友任九晗发文悼念,称从没想过再次见面,是看着你从冷柜里被抬出...
800元免费领,让养老院“头疼... “没想到,都快5月了,在我们这么大的社区,我是第一个申领养老消费券的人。”4月下旬,在90多岁父亲出...
方太燃气灶打不上火是什么原因? 可能是燃气灶 没有开燃气阀,有的时候是忘记开燃气阀门了;可能是燃气灶喷嘴堵塞,影响喷嘴点燃燃气;还可...
带熄火保护的燃气灶不出气怎么办 开启开关出现了故障,如果是带熄火保护的燃气灶由于使用年限过长,导致出现问题,则意味着无法正常进行使用...