浅谈create table as 和 insert into select 复制表遇到的问题

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: 之前做一次表压缩测试,在准备原表时需要数据量比较大的表,通过insert into select 的方式将几个表的数据复制到一个表,产生的一些问题~

1、 新建一个表,表结构与原表是相同的。建表语句:
CREATE TABLE huayu_test1 (
waybill_id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '?????',
waybill_no varchar(20) NOT NULL COMMENT '???',
post_date datetime NOT NULL COMMENT '????????',
order_id varchar(50) DEFAULT NULL COMMENT '?????????',
batch_no varchar(50) DEFAULT NULL COMMENT '???',
biz_product_id varchar(20) NOT NULL COMMENT '??????',
biz_product_no varchar(20) NOT NULL COMMENT '??????',
biz_product_name varchar(50) NOT NULL COMMENT '??????',
sender_type varchar(20) DEFAULT NULL COMMENT '0 ?? 1????',
sender_id varchar(50) DEFAULT NULL COMMENT '??????',
sender_no varchar(50) DEFAULT NULL COMMENT '??????(??????)',
sender varchar(200) DEFAULT NULL COMMENT '??????',
sender_linker varchar(200) DEFAULT NULL,
sender_fixtel varchar(50) DEFAULT NULL COMMENT '??????',
sender_mobile varchar(50) DEFAULT NULL COMMENT '??????',
sender_addr varchar(200) DEFAULT NULL COMMENT '??????',
sender_country_no varchar(20) DEFAULT NULL COMMENT '??????',
sender_country_name varchar(50) DEFAULT NULL COMMENT '??????',
sender_province_no varchar(20) DEFAULT NULL COMMENT '??????',
sender_province_name varchar(50) DEFAULT NULL COMMENT '??????',
sender_city_no varchar(20) DEFAULT NULL COMMENT '??????',
sender_city_name varchar(50) DEFAULT NULL COMMENT '??????',
sender_county_no varchar(20) DEFAULT NULL COMMENT '??????',
sender_county_name varchar(50) DEFAULT NULL COMMENT '??????',
sender_notes varchar(1000) DEFAULT NULL COMMENT '????',
receiver_no varchar(50) DEFAULT NULL COMMENT '??????????????',
receiver varchar(200) DEFAULT NULL COMMENT '??????',
receiver_linker varchar(200) DEFAULT NULL,
receiver_fixtel varchar(50) DEFAULT NULL COMMENT '??????',
receiver_mobile varchar(50) DEFAULT NULL COMMENT '??????',
receiver_addr varchar(200) DEFAULT NULL COMMENT '??????',
receiver_country_no varchar(20) DEFAULT NULL COMMENT '??????',
receiver_country_name varchar(50) DEFAULT NULL COMMENT '??????',
receiver_province_no varchar(20) DEFAULT NULL COMMENT '??????',
receiver_province_name varchar(50) DEFAULT NULL COMMENT '??????',
receiver_city_no varchar(20) DEFAULT NULL COMMENT '??????',
receiver_city_name varchar(50) DEFAULT NULL COMMENT '??????',
receiver_county_no varchar(20) DEFAULT NULL COMMENT '??????',
receiver_county_name varchar(50) DEFAULT NULL COMMENT '??????',
insurance_flag char(1) DEFAULT NULL COMMENT '????????????1:?? 2:?? 3:??',
insurance_amount decimal(12,2) DEFAULT NULL COMMENT '??????',
pickup_type varchar(20) DEFAULT NULL COMMENT '?????0 ???????1 ??????',
payment_mode varchar(20) DEFAULT NULL COMMENT '????(???) 1:??? 2:??? 3:??? 4:??????? 5:?? 6:?/??? 7:???',
real_weight decimal(8,0) DEFAULT NULL COMMENT '????',
fee_weight decimal(8,0) DEFAULT NULL,
volume_weight decimal(8,0) DEFAULT NULL,
length decimal(8,0) DEFAULT NULL,
width decimal(8,0) DEFAULT NULL,
height decimal(8,0) DEFAULT NULL,
quantity int(11) DEFAULT NULL,
packaging varchar(20) DEFAULT NULL,
package_material varchar(20) DEFAULT NULL,
goods_desc varchar(200) DEFAULT NULL,
contents_quantity int(11) DEFAULT NULL,
cod_flag char(1) DEFAULT NULL,
cod_amount decimal(12,2) DEFAULT NULL,
receipt_flag char(1) DEFAULT NULL,
receipt_waybill_no varchar(20) DEFAULT NULL,
receipt_fee_amount decimal(12,2) DEFAULT NULL,
insurance_premium_amount decimal(12,2) DEFAULT NULL,
valuable_flag char(1) DEFAULT NULL,
cargo_total_price decimal(12,2) DEFAULT NULL,
cargo_total_purchasing_price decimal(12,2) DEFAULT NULL,
allow_fee_flag char(1) DEFAULT NULL,
is_feed_flag char(1) DEFAULT NULL,
manual_fee_type char(1) DEFAULT NULL,
fee_date datetime DEFAULT NULL,
discount_rate decimal(6,2) DEFAULT NULL,
settlement_mode varchar(20) DEFAULT NULL,
payment_state char(1) DEFAULT NULL,
payment_date datetime DEFAULT NULL,
payment_id varchar(50) DEFAULT NULL,
manage_org_code varchar(20) DEFAULT NULL,
postage_suite_code varchar(20) DEFAULT NULL,
fee_area_suite_code varchar(20) DEFAULT NULL,
fee_area_code varchar(20) DEFAULT NULL,
fee_area_name varchar(20) DEFAULT NULL,
is_advance_flag char(1) DEFAULT NULL,
deliver_type char(1) DEFAULT NULL,
deliver_sign varchar(50) DEFAULT NULL,
deliver_date char(1) DEFAULT NULL,
deliver_notes varchar(1000) DEFAULT NULL,
deliver_pre_date date DEFAULT NULL,
battery_flag char(1) DEFAULT NULL,
is_jinguan varchar(20) DEFAULT NULL,
workbench varchar(20) DEFAULT NULL,
electronic_preferential_no varchar(50) DEFAULT NULL,
electronic_preferential_amount decimal(12,2) DEFAULT NULL,
pickup_attribute char(1) DEFAULT NULL,
adjust_type varchar(20) DEFAULT NULL,
postage_revoke decimal(12,2) DEFAULT NULL,
print_flag char(1) DEFAULT NULL,
print_date datetime DEFAULT NULL,
print_times int(11) DEFAULT NULL,
declare_source varchar(20) DEFAULT NULL,
declare_type varchar(20) DEFAULT NULL,
declare_curr_code varchar(20) DEFAULT NULL,
create_user_name varchar(50) DEFAULT NULL,
modify_user_name varchar(50) DEFAULT NULL,
volume decimal(8,0) DEFAULT NULL COMMENT '??',
contents_type_no varchar(20) DEFAULT NULL COMMENT '??????',
contents_type_name varchar(200) DEFAULT NULL COMMENT '??????',
contents_weight decimal(8,0) DEFAULT NULL COMMENT '??????',
transfer_type varchar(20) DEFAULT NULL COMMENT '????',
postage_total decimal(12,2) NOT NULL COMMENT '???=????+????',
postage_standard decimal(12,2) DEFAULT NULL COMMENT '????',
postage_paid decimal(12,2) DEFAULT NULL COMMENT '????',
postage_other decimal(12,2) DEFAULT NULL COMMENT '????',
is_deleted char(1) DEFAULT '0' COMMENT '?????n0??n1??',
create_user_id bigint(20) DEFAULT NULL COMMENT '???id',
gmt_created datetime DEFAULT NULL COMMENT '????',
modify_user_id bigint(20) DEFAULT NULL COMMENT '???id',
gmt_modified datetime DEFAULT NULL COMMENT '????',
reserved1 bigint(20) DEFAULT NULL COMMENT '????1',
reserved2 bigint(20) DEFAULT NULL COMMENT '????2',
reserved3 bigint(20) DEFAULT NULL COMMENT '????3',
reserved4 varchar(200) DEFAULT NULL COMMENT '????4',
reserved5 varchar(200) DEFAULT NULL COMMENT '????5',
reserved6 varchar(200) DEFAULT NULL COMMENT '????6',
reserved7 varchar(200) DEFAULT NULL COMMENT '????7',
reserved8 varchar(200) DEFAULT NULL COMMENT '????8',
reserved9 datetime DEFAULT NULL COMMENT '????9',
reserved10 text COMMENT '????10',
logistics_order_no bigint(50) DEFAULT NULL,
inner_channel varchar(20) DEFAULT NULL,
base_product_id bigint(20) DEFAULT NULL,
base_product_no varchar(20) DEFAULT NULL,
base_product_name varchar(20) DEFAULT NULL,
is_special_marketing char(1) DEFAULT NULL,
product_type varchar(20) DEFAULT NULL,
biz_product_type varchar(20) DEFAULT NULL,
product_reach_area char(1) DEFAULT NULL,
contents_attribute char(1) DEFAULT NULL,
contents_cargo_no varchar(1000) DEFAULT NULL,
cmd_code varchar(20) DEFAULT NULL,
manual_charge_reason varchar(200) DEFAULT NULL,
time_limit char(1) DEFAULT NULL,
io_type varchar(20) DEFAULT NULL,
ecommerce_no varchar(20) DEFAULT NULL,
waybill_type varchar(20) DEFAULT NULL,
pre_waybill_no varchar(50) DEFAULT NULL,
post_batch_id varchar(50) DEFAULT NULL,
biz_occur_date datetime DEFAULT NULL,
post_org_id bigint(20) DEFAULT NULL,
post_org_no varchar(50) DEFAULT NULL,
org_drds_code varchar(50) DEFAULT NULL,
post_org_simple_name varchar(50) DEFAULT NULL,
post_org_product_name varchar(20) DEFAULT NULL,
post_person_id bigint(20) DEFAULT NULL,
post_person_no varchar(50) DEFAULT NULL,
post_person_name varchar(50) DEFAULT NULL,
post_person_mobile varchar(50) DEFAULT NULL,
sender_warehouse_id bigint(20) DEFAULT NULL,
sender_warehouse_name varchar(200) DEFAULT NULL,
sender_safety_code varchar(50) DEFAULT NULL,
sender_im_type varchar(20) DEFAULT NULL,
sender_im_id varchar(50) DEFAULT NULL,
sender_id_type varchar(20) DEFAULT NULL,
sender_id_no varchar(50) DEFAULT NULL,
sender_id_encrypted_code varchar(50) DEFAULT NULL,
sender_agent_id_type varchar(20) DEFAULT NULL,
sender_agent_id_no varchar(50) DEFAULT NULL,
sender_id_encrypted_code_agent varchar(50) DEFAULT NULL,
sender_addr_additional varchar(200) DEFAULT NULL,
sender_district_no varchar(20) DEFAULT NULL,
sender_postcode varchar(20) DEFAULT NULL,
sender_gis varchar(20) DEFAULT NULL,
registered_customer_no varchar(50) DEFAULT NULL,
receiver_type char(1) DEFAULT NULL,
receiver_id bigint(20) DEFAULT NULL,
receiver_warehouse_id bigint(20) DEFAULT NULL,
receiver_warehouse_name varchar(200) DEFAULT NULL,
receiver_safety_code varchar(50) DEFAULT NULL,
receiver_im_type varchar(20) DEFAULT NULL,
receiver_im_id varchar(50) DEFAULT NULL,
receiver_addr_additional varchar(200) DEFAULT NULL,
receiver_district_no varchar(20) DEFAULT NULL,
receiver_postcode varchar(20) DEFAULT NULL,
receiver_gis varchar(20) DEFAULT NULL,
receiver_notes varchar(1000) DEFAULT NULL,
customer_manager_id bigint(20) DEFAULT NULL,
customer_manager_no varchar(50) DEFAULT NULL,
customer_manager_name varchar(50) DEFAULT NULL,
salesman_id bigint(20) DEFAULT NULL,
salesman_no varchar(50) DEFAULT NULL,
salesman_name varchar(50) DEFAULT NULL,
order_weight decimal(8,0) DEFAULT NULL,
post_org_name varchar(200) DEFAULT NULL,
PRIMARY KEY (waybill_id),
KEY auto_shard_key_post_date (post_date),
KEY auto_shard_key_waybill_no (waybill_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='???????';
2、 原表数据量

mysql> select concat(round(sum(data_length/1024/1024/1024),3),'G') from information_schema.tables where table_name='qps_waybill_base_02';
concat(round(sum(data_length/1024/1024/1024),3),'G')
18.636G

1 row in set (0.00 sec)

3、 执行命令insert into 复制表
mysql> insert into huayu_test1 select * from qps_waybill_base_02;
Query OK, 15861881 rows affected (16 min 8.37 sec)
Records: 15861881 Duplicates: 0 Warnings: 0

数据量:

mysql> select concat(round(sum(data_length/1024/1024/1024),3),'G') from information_schema.tables where table_name='huayu_test1';
concat(round(sum(data_length/1024/1024/1024),3),'G')
9.174G

1 row in set (0.00 sec)

4、 执行命令create table as select 复制表
mysql> create table huayu_test2 as select * from qps_waybill_base_02;
Query OK, 15861881 rows affected (14 min 44.98 sec)
Records: 15861881 Duplicates: 0 Warnings: 0

数据量

mysql> select concat(round(sum(data_length/1024/1024/1024),3),'G') from information_schema.tables where table_name='huayu_test2';
concat(round(sum(data_length/1024/1024/1024),3),'G')
9.818G

1 row in set (0.00 sec)

5、数据行数

mysql> select count(*) from huayu_test2;
count(*)
15861881

1 row in set (4.12 sec)

mysql> select count(*) from huayu_test1;
count(*)
15861881

1 row in set (7.00 sec)

mysql>

.ibd文件大小对比

ll -h

total 44G
-rw-rw---- 1 mysql mysql 61 May 3 2017 db.opt
-rw-rw---- 1 mysql mysql 51K Feb 2 09:33 huayu_test1.frm
-rw-rw---- 1 mysql mysql 12G Feb 2 09:49 huayu_test1.ibd
-rw-rw---- 1 mysql mysql 52K Feb 2 09:59 huayu_test2.frm
-rw-rw---- 1 mysql mysql 11G Feb 2 10:13 huayu_test2.ibd

6、由于源表是通过inert into select 将实际的生产上的表拼接起来的,现在以新建的huayu_test1为源表进行测试,这个表是通过inert into select 源表 新建的表,数据量如下分别为insert into select 、 create table as select 和 新的源表:

mysql> select concat(round(sum(data_length/1024/1024/1024),3),'G') from information_schema.tables where table_name='huayu_test1_2';
concat(round(sum(data_length/1024/1024/1024),3),'G')
9.472G

1 row in set (0.00 sec)

mysql> select concat(round(sum(data_length/1024/1024/1024),3),'G') from information_schema.tables where table_name='huayu_test1_1';
concat(round(sum(data_length/1024/1024/1024),3),'G')
9.364G

1 row in set (0.00 sec)

mysql> select concat(round(sum(data_length/1024/1024/1024),3),'G') from information_schema.tables where table_name='huayu_test1';
concat(round(sum(data_length/1024/1024/1024),3),'G')
9.174G

1 row in set (0.00 sec)

mysql>

从这里看,数据量的大小还是差不多的。
7、比较一下:
mysql> show table status like 'qps_waybill_base_02'G
1. row **

       Name: qps_waybill_base_02
     Engine: InnoDB
    Version: 10
 Row_format: Compact
       Rows: 15109587

Avg_row_length: 1324

Data_length: 20009975808

Max_data_length: 0
Index_length: 1240465408

  Data_free: 7340032

Auto_increment: 568964219

Create_time: 2018-01-24 09:42:57
Update_time: NULL
 Check_time: NULL
  Collation: utf8_general_ci
   Checksum: NULL

Create_options:

    Comment: ???????

Block_format: Original
1 row in set (0.00 sec)

mysql> show table status like 'huayu_test1'G
1. row **

       Name: huayu_test1
     Engine: InnoDB
    Version: 10
 Row_format: Compact
       Rows: 15412951

Avg_row_length: 639

Data_length: 9850322944

Max_data_length: 0
Index_length: 1268776960

  Data_free: 7340032

Auto_increment: 568964219

Create_time: 2018-02-02 09:33:40
Update_time: NULL
 Check_time: NULL
  Collation: utf8_general_ci
   Checksum: NULL

Create_options:

    Comment: ???????

Block_format: Original
1 row in set (0.01 sec)

mysql> show table status like 'huayu_test1_1'G
1. row **

       Name: huayu_test1_1
     Engine: InnoDB
    Version: 10
 Row_format: Compact
       Rows: 15310307

Avg_row_length: 656

Data_length: 10054795264

Max_data_length: 0
Index_length: 286179328

  Data_free: 4194304

Auto_increment: 15925006

Create_time: 2018-02-02 10:27:47
Update_time: NULL
 Check_time: NULL
  Collation: utf8_general_ci
   Checksum: NULL

Create_options:

    Comment: 

Block_format: Original
1 row in set (0.00 sec)

mysql> show table status like 'huayu_test1_2'G
1. row **

       Name: huayu_test1_2
     Engine: InnoDB
    Version: 10
 Row_format: Compact
       Rows: 14912979

Avg_row_length: 681

Data_length: 10170138624

Max_data_length: 0
Index_length: 1307574272

  Data_free: 7340032

Auto_increment: 568964219

Create_time: 2018-02-02 10:42:09
Update_time: NULL
 Check_time: NULL
  Collation: utf8_general_ci
   Checksum: NULL

Create_options:

    Comment: ???????

Block_format: Original
1 row in set (0.00 sec)
8、在源表执行了optimize table 之后,数据变成了10G左右,跟复制后的表的数据相近了

mysql> select concat(round(sum(data_length/1024/1024/1024),3),'G') from information_schema.tables where table_name='qps_waybill_base_02';
concat(round(sum(data_length/1024/1024/1024),3),'G')
10.041G

1 row in set (0.00 sec)
9、初步结论

1、Create table as 比 insert into select 的速度更快,但是经实验创建表后的数据大小insert into select占用的数据量比较小。Create 是ddl语句,insert 是dml语句,insert的时候每条语句都会产生对应的redo和undo日志,所以相对create 语句是慢一些的。
官方文档说明:Create table as 语句不会复制原表的索引,如果想要复制索引的话,需要指定索引
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;

还有可能会发生数据类型的转换。例如,auto_increment列的属性不会保留,varchar列会转换成char列,
但是原表的数据量相比create 和 insert 复制后的表为什么会这么大,而重新复制一个相同的原表后,用新的原表测试后create 和insert 复制后的数据量就差不多了。怀疑是生产上的原表可能有一些多余的东西,或者表在合并的过程中有空隙只是占用表空间,而没有存储数据 。
2、Optimize table:InnoDB表上进行大量插入、更新或删除操作之后。ibd文件,因为它是通过启用innodb_file_per_table选项创建的。重新组织了表和索引,操作系统可以回收磁盘空间。

在delete 很大空间之后,这个空间不会被立即删除,而是等待新的插入的数据进行填充,后续的insert 数据会占用旧的位置,使用OPTIMIZE TABLE来重新利用未使用的空间,并整理数据文件的碎片,这个是针对myisam表和archive表的。

对于InnoDB表,Optimize table映射到ALTER TABLE…FORCE,它重新构建表以更新索引统计数据和聚集索引中的空闲未使用空间。在InnoDB表上运行时,optimize table 的时候会报这样的信息:Table does not support optimize, doing recreate + analyze instead。 会自动重建一个表再使用analyze命令进行优化
Analyse table是对表的索引分布进行分析,优化表的索引的性能

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
搜索推荐 安全 UED
浅谈AARRR模型
浅谈AARRR模型
|
存储 缓存 负载均衡
Nginx入门笔记
Nginx入门笔记
547 0
|
SQL 数据库
SQL INSERT INTO SELECT 语句
SQL INSERT INTO SELECT 语句
2825 8
|
10月前
|
监控 搜索推荐 数据挖掘
【开发者必看—电商篇】数据赋能电商App活跃度重焕新生
通过友盟+数据分析工具的综合数据分析和个性化推送功能,解决APP用户活跃度迅速下降的问题。
|
存储 关系型数据库 MySQL
技术解析:MySQL中取最新一条重复数据的方法
以上提供的两种方法都可以有效地从MySQL数据库中提取每个类别最新的重复数据。选择哪种方法取决于具体的使用场景和MySQL版本。子查询加分组的方法兼容性更好,适用于所有版本的MySQL;而窗口函数方法代码更简洁,执行效率可能更高,但需要MySQL 8.0及以上版本。在实际应用中,应根据数据量大小、查询性能需求以及MySQL版本等因素综合考虑,选择最合适的实现方案。
1244 6
|
存储 缓存 前端开发
聊聊公众号联动扫码登录功能如何实现
【10月更文挑战第30天】公众号联动扫码登录功能的实现涉及前端、后端与微信平台的交互。前端设计二维码展示区和轮询机制,后端负责生成二维码、处理微信推送、用户身份验证及登录。整个过程需确保数据交互安全顺畅,提升用户体验。
456 1
|
小程序 搜索推荐 算法
计算机毕业设计参考-微信小程序实现的校园餐饮预订与点餐平台源码
该系统分为管理端、小程序用户端和商户端三部分。管理端提供商品分类、商品、评价、订单和用户管理等功能,以及商户管理功能,可以管理商户信息、发布商品、查看店铺订单等。小程序用户端提供商品浏览、商品搜索、购物车、商品下单、个人信息、收货地址等功能,并使用基于协同过滤的推荐算法进行商品推荐。商户端提供与管理端相同的功能,并可以设置店铺信息和发布商品。用户和商户可以使用手机号码登录,获取验证码登录系统。该系统为校园点餐提供了一种方便快捷的解决方案,可以有效提升用户点餐的体验和商户的管理效率。
|
弹性计算 云计算 开发者
阿里云服务器租用价格表整理汇总,2024年阿里云价格表查询整理
在云计算服务市场上,阿里云凭借其卓越的性能和稳定的品质,赢得了广大用户的信赖。对于许多个人开发者和小型企业来说,选择阿里云的服务器往往是一个明智的选择。那么,阿里云服务器的租用价格是怎样的呢?今天我们就为大家带来最新的阿里云服务器租用价格表。
|
存储 监控 Apache
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
网易的灵犀办公和云信利用 Apache Doris 改进了大规模日志和时序数据处理,取代了 Elasticsearch 和 InfluxDB。Doris 实现了更低的服务器资源消耗和更高的查询性能,相比 Elasticsearch,查询速度提升至少 11 倍,存储资源节省达 70%。Doris 的列式存储、高压缩比和倒排索引等功能,优化了日志和时序数据的存储与分析,降低了存储成本并提高了查询效率。在灵犀办公和云信的实际应用中,Doris 显示出显著的性能优势,成功应对了数据增长带来的挑战。
53820 2
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
|
机器学习/深度学习 人工智能 算法
计算机与机械专业的关系——未来100年必备——南天门计划
计算机与机械专业的关系——未来100年必备——南天门计划
327 0