久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術文章
文章詳情頁

淺談為什么MySQL不建議delete刪除數據

瀏覽:91日期:2023-10-07 09:32:33
前言

我負責的有幾個系統隨著業務量的增長,存儲在MySQL中的數據日益劇增,我當時就想現在的業務方不講武德,搞偷襲,趁我沒反應過來把很多表,很快,很快啊都打到了億級別,我大意了,沒有閃,這就導致跟其Join的表的SQL變得很慢,對的應用接口的response time也變長了,影響了用戶體驗。

事后我找到業務方,我批評了他們跟他們說要講武德,連忙跟我道歉,這個事情才就此作罷,走的時候我對他們說下次不要這樣了,耗子尾汁,好好反思。

罵歸罵,事情還是得解決,時候我分析原因發現,發現有些表的數據量增長很快,對應SQL掃描了很多無效數據,導致SQL慢了下來,通過確認之后,這些大表都是一些流水、記錄、日志類型數據,只需要保留1到3個月,此時需要對表做數據清理實現瘦身,一般都會想到用insert + delete的方式去清理。

這篇文章我會從InnoDB存儲空間分布,delete對性能的影響,以及優化建議方面解釋為什么不建議delete刪除數據。

InnoDB存儲架構

淺談為什么MySQL不建議delete刪除數據

從這張圖可以看到,InnoDB存儲結構主要包括兩部分:邏輯存儲結構和物理存儲結構。

邏輯上是由表空間tablespace —> 段segment或者inode —> 區Extent ——>數據頁Page構成,Innodb邏輯管理單位是segment,空間分配的最小單位是extent,每個segment都會從表空間FREE_PAGE中分配32個page,當這32個page不夠用時,會按照以下原則進行擴展:如果當前小于1個extent,則擴展到1個extent;當表空間小于32MB時,每次擴展一個extent;表空間大于32MB,每次擴展4個extent。

物理上主要由系統用戶數據文件,日志文件組成,數據文件主要存儲MySQL字典數據和用戶數據,日志文件記錄的是data page的變更記錄,用于MySQL Crash時的恢復。

Innodb表空間

InnoDB存儲包括三類表空間:系統表空間,用戶表空間,Undo表空間。

**系統表空間:**主要存儲MySQL內部的數據字典數據,如information_schema下的數據。

**用戶表空間:**當開啟innodb_file_per_table=1時,數據表從系統表空間獨立出來存儲在以table_name.ibd命令的數據文件中,結構信息存儲在table_name.frm文件中。

**Undo表空間:**存儲Undo信息,如快照一致讀和flashback都是利用undo信息。

從MySQL 8.0開始允許用戶自定義表空間,具體語法如下:

CREATE TABLESPACE tablespace_name ADD DATAFILE ’file_name’#數據文件名 USE LOGFILE GROUP logfile_group #自定義日志文件組,一般每組2個logfile。 [EXTENT_SIZE [=] extent_size] #區大小 [INITIAL_SIZE [=] initial_size] #初始化大小 [AUTOEXTEND_SIZE [=] autoextend_size] #自動擴寬尺寸 [MAX_SIZE [=] max_size]#單個文件最大size,最大是32G。 [NODEGROUP [=] nodegroup_id] #節點組 [WAIT] [COMMENT [=] comment_text] ENGINE [=] engine_name

這樣的好處是可以做到數據的冷熱分離,分別用HDD和SSD來存儲,既能實現數據的高效訪問,又能節約成本,比如可以添加兩塊500G硬盤,經過創建卷組vg,劃分邏輯卷lv,創建數據目錄并mount相應的lv,假設劃分的兩個目錄分別是/hot_data 和 /cold_data。

這樣就可以將核心的業務表如用戶表,訂單表存儲在高性能SSD盤上,一些日志,流水表存儲在普通的HDD上,主要的操作步驟如下:

#創建熱數據表空間create tablespace tbs_data_hot add datafile ’/hot_data/tbs_data_hot01.dbf’ max_size 20G;#創建核心業務表存儲在熱數據表空間create table booking(id bigint not null primary key auto_increment, …… ) tablespace tbs_data_hot;#創建冷數據表空間create tablespace tbs_data_cold add datafile ’/hot_data/tbs_data_cold01.dbf’ max_size 20G;#創建日志,流水,備份類的表存儲在冷數據表空間create table payment_log(id bigint not null primary key auto_increment, …… ) tablespace tbs_data_cold;#可以移動表到另一個表空間alter table payment_log tablespace tbs_data_hot;Inndob存儲分布創建空表查看空間變化

mysql> create table user(id bigint not null primary key auto_increment, -> name varchar(20) not null default ’’ comment ’姓名’, -> age tinyint not null default 0 comment ’age’, -> gender char(1) not null default ’M’ comment ’性別’, -> phone varchar(16) not null default ’’ comment ’手機號’, -> create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ’創建時間’, -> update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ’修改時間’ -> ) engine = InnoDB DEFAULT CHARSET=utf8mb4 COMMENT ’用戶信息表’;Query OK, 0 rows affected (0.26 sec)

# ls -lh user1.ibd -rw-r----- 1 mysql mysql 96K Nov 6 12:48 user.ibd

設置參數innodb_file_per_table=1時,創建表時會自動創建一個segment,同時分配一個extent,包含32個data page的來存儲數據,這樣創建的空表默認大小就是96KB,extent使用完之后會申請64個連接頁,這樣對于一些小表,或者undo segment,可以在開始時申請較少的空間,節省磁盤容量的開銷。

# python2 py_innodb_page_info.py -v /data2/mysql/test/user.ibdpage offset 00000000, page type <File Space Header>page offset 00000001, page type <Insert Buffer Bitmap>page offset 00000002, page type <File Segment inode>page offset 00000003, page type <B-tree Node>, page level <0000>page offset 00000000, page type <Freshly Allocated Page>page offset 00000000, page type <Freshly Allocated Page>Total number of page: 6: #總共分配的頁數Freshly Allocated Page: 2 #可用的數據頁Insert Buffer Bitmap: 1 #插入緩沖頁File Space Header: 1 #文件空間頭B-tree Node: 1#數據頁File Segment inode: 1 #文件端inonde,如果是在ibdata1.ibd上會有多個inode。插入數據后的空間變化

mysql> DELIMITER $$mysql> CREATE PROCEDURE insert_user_data(num INTEGER) -> BEGIN -> DECLARE v_i int unsigned DEFAULT 0; -> set autocommit= 0; -> WHILE v_i < num DO -> insert into user(`name`, age, gender, phone) values (CONCAT(’lyn’,v_i), mod(v_i,120), ’M’, CONCAT(’152’,ROUND(RAND(1)*100000000))); -> SET v_i = v_i+1; -> END WHILE; -> commit; -> END $$Query OK, 0 rows affected (0.01 sec)mysql> DELIMITER ;#插入10w數據mysql> call insert_user_data(100000);Query OK, 0 rows affected (6.69 sec)

# ls -lh user.ibd-rw-r----- 1 mysql mysql 14M Nov 6 10:58 /data2/mysql/test/user.ibd# python2 py_innodb_page_info.py -v /data2/mysql/test/user.ibdpage offset 00000000, page type <File Space Header>page offset 00000001, page type <Insert Buffer Bitmap>page offset 00000002, page type <File Segment inode>page offset 00000003, page type <B-tree Node>, page level <0001> #增加了一個非葉子節點,樹的高度從1變為2.........................................................page offset 00000000, page type <Freshly Allocated Page>Total number of page: 896:Freshly Allocated Page: 493Insert Buffer Bitmap: 1File Space Header: 1B-tree Node: 400File Segment inode: 1delete數據后的空間變化

mysql> select min(id),max(id),count(*) from user;+---------+---------+----------+| min(id) | max(id) | count(*) |+---------+---------+----------+| 1 | 100000 | 100000 |+---------+---------+----------+1 row in set (0.05 sec)#刪除50000條數據,理論上空間應該從14MB變長7MB左右。mysql> delete from user limit 50000;Query OK, 50000 rows affected (0.25 sec) #數據文件大小依然是14MB,沒有縮小。# ls -lh /data2/mysql/test/user1.ibd -rw-r----- 1 mysql mysql 14M Nov 6 13:22 /data2/mysql/test/user.ibd#數據頁沒有被回收。# python2 py_innodb_page_info.py -v /data2/mysql/test/user.ibdpage offset 00000000, page type <File Space Header>page offset 00000001, page type <Insert Buffer Bitmap>page offset 00000002, page type <File Segment inode>page offset 00000003, page type <B-tree Node>, page level <0001>........................................................page offset 00000000, page type <Freshly Allocated Page>Total number of page: 896:Freshly Allocated Page: 493Insert Buffer Bitmap: 1File Space Header: 1B-tree Node: 400File Segment inode: 1#在MySQL內部是標記刪除,

mysql> use information_schema;Database changedmysql> SELECT A.SPACE AS TBL_SPACEID, A.TABLE_ID, A.NAME AS TABLE_NAME, FILE_FORMAT, ROW_FORMAT, SPACE_TYPE, B.INDEX_ID , B.NAME AS INDEX_NAME, PAGE_NO, B.TYPE AS INDEX_TYPE FROM INNODB_SYS_TABLES A LEFT JOIN INNODB_SYS_INDEXES B ON A.TABLE_ID =B.TABLE_ID WHERE A.NAME = ’test/user1’;+-------------+----------+------------+-------------+------------+------------+----------+------------+---------+------------+| TBL_SPACEID | TABLE_ID | TABLE_NAME | FILE_FORMAT | ROW_FORMAT | SPACE_TYPE | INDEX_ID | INDEX_NAME | PAGE_NO | INDEX_TYPE |+-------------+----------+------------+-------------+------------+------------+----------+------------+---------+------------+| 1283 | 1207 | test/user | Barracuda | Dynamic | Single | 2236 | PRIMARY | 3 | 3 |+-------------+----------+------------+-------------+------------+------------+----------+------------+---------+------------+1 row in set (0.01 sec)PAGE_NO = 3 標識B-tree的root page是3號頁,INDEX_TYPE = 3是聚集索引。 INDEX_TYPE取值如下:0 = nonunique secondary index; 1 = automatically generated clustered index (GEN_CLUST_INDEX); 2 = unique nonclustered index; 3 = clustered index; 32 = full-text index;#收縮空間再后進行觀察

MySQL內部不會真正刪除空間,而且做標記刪除,即將delflag:N修改為delflag:Y,commit之后會會被purge進入刪除鏈表,如果下一次insert更大的記錄,delete之后的空間不會被重用,如果插入的記錄小于等于delete的記錄空會被重用,這塊內容可以通過知數堂的innblock工具進行分析。

Innodb中的碎片碎片的產生

我們知道數據存儲在文件系統上的,總是不能100%利用分配給它的物理空間,刪除數據會在頁面上留下一些”空洞”,或者隨機寫入(聚集索引非線性增加)會導致頁分裂,頁分裂導致頁面的利用空間少于50%,另外對表進行增刪改會引起對應的二級索引值的隨機的增刪改,也會導致索引結構中的數據頁面上留下一些'空洞',雖然這些空洞有可能會被重復利用,但終究會導致部分物理空間未被使用,也就是碎片。

同時,即便是設置了填充因子為100%,Innodb也會主動留下page頁面1/16的空間作為預留使用(An innodb_fill_factor setting of 100 leaves 1/16 of the space in clustered index pages free for future index growth)防止update帶來的行溢出。

mysql> select table_schema, -> table_name,ENGINE, -> round(DATA_LENGTH/1024/1024+ INDEX_LENGTH/1024/1024) total_mb,TABLE_ROWS, -> round(DATA_LENGTH/1024/1024) data_mb, round(INDEX_LENGTH/1024/1024) index_mb, round(DATA_FREE/1024/1024) free_mb, round(DATA_FREE/DATA_LENGTH*100,2) free_ratio -> from information_schema.TABLES where TABLE_SCHEMA= ’test’ -> and TABLE_NAME= ’user’;+--------------+------------+--------+----------+------------+---------+----------+---------+------------+| table_schema | table_name | ENGINE | total_mb | TABLE_ROWS | data_mb | index_mb | free_mb | free_ratio |+--------------+------------+--------+----------+------------+---------+----------+---------+------------+| test | user | InnoDB | 4 | 50000 | 4 | 0 | 6 | 149.42 |+--------------+------------+--------+----------+------------+---------+----------+---------+------------+1 row in set (0.00 sec)

其中data_free是分配了未使用的字節數,并不能說明完全是碎片空間。

碎片的回收

對于InnoDB的表,可以通過以下命令來回收碎片,釋放空間,這個是隨機讀IO操作,會比較耗時,也會阻塞表上正常的DML運行,同時需要占用額外更多的磁盤空間,對于RDS來說,可能會導致磁盤空間瞬間爆滿,實例瞬間被鎖定,應用無法做DML操作,所以禁止在線上環境去執行。

#執行InnoDB的碎片回收mysql> alter table user engine=InnoDB;Query OK, 0 rows affected (9.00 sec)Records: 0 Duplicates: 0 Warnings: 0##執行完之后,數據文件大小從14MB降低到10M。# ls -lh /data2/mysql/test/user1.ibd -rw-r----- 1 mysql mysql 10M Nov 6 16:18 /data2/mysql/test/user.ibd

mysql> select table_schema, table_name,ENGINE, round(DATA_LENGTH/1024/1024+ INDEX_LENGTH/1024/1024) total_mb,TABLE_ROWS, round(DATA_LENGTH/1024/1024) data_mb, round(INDEX_LENGTH/1024/1024) index_mb, round(DATA_FREE/1024/1024) free_mb, round(DATA_FREE/DATA_LENGTH*100,2) free_ratio from information_schema.TABLES where TABLE_SCHEMA= ’test’ and TABLE_NAME= ’user’;+--------------+------------+--------+----------+------------+---------+----------+---------+------------+| table_schema | table_name | ENGINE | total_mb | TABLE_ROWS | data_mb | index_mb | free_mb | free_ratio |+--------------+------------+--------+----------+------------+---------+----------+---------+------------+| test | user | InnoDB | 5 | 50000 | 5 | 0 | 2 | 44.29 |+--------------+------------+--------+----------+------------+---------+----------+---------+------------+1 row in set (0.00 sec)delete對SQL的影響未刪除前的SQL執行情況

#插入100W數據mysql> call insert_user_data(1000000);Query OK, 0 rows affected (35.99 sec)#添加相關索引mysql> alter table user add index idx_name(name), add index idx_phone(phone);Query OK, 0 rows affected (6.00 sec)Records: 0 Duplicates: 0 Warnings: 0#表上索引統計信息mysql> show index from user;+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| user | 0 | PRIMARY | 1 | id | A | 996757 | NULL | NULL | | BTREE | ||| user | 1 | idx_name | 1 | name | A | 996757 | NULL | NULL | | BTREE | ||| user | 1 | idx_phone | 1 | phone | A | 2 | NULL | NULL | | BTREE | ||+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+3 rows in set (0.00 sec)#重置狀態變量計數mysql> flush status;Query OK, 0 rows affected (0.00 sec)#執行SQL語句mysql> select id, age ,phone from user where name like ’lyn12%’;+--------+-----+-------------+| id | age | phone |+--------+-----+-------------+| 124 | 3 | 15240540354 || 1231 | 30 | 15240540354 || 12301 | 60 | 15240540354 |.............................| 129998 | 37 | 15240540354 || 129999 | 38 | 15240540354 || 130000 | 39 | 15240540354 |+--------+-----+-------------+11111 rows in set (0.03 sec)mysql> explain select id, age ,phone from user where name like ’lyn12%’;+----+-------------+-------+-------+---------------+----------+---------+------+-------+-----------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+-------+---------------+----------+---------+------+-------+-----------------------+| 1 | SIMPLE | user | range | idx_name | idx_name | 82 | NULL | 22226 | Using index condition |+----+-------------+-------+-------+---------------+----------+---------+------+-------+-----------------------+1 row in set (0.00 sec)#查看相關狀態呢變量mysql> select * from information_schema.session_status where variable_name in(’Last_query_cost’,’Handler_read_next’,’Innodb_pages_read’,’Innodb_data_reads’,’Innodb_pages_read’);+-------------------+----------------+| VARIABLE_NAME | VARIABLE_VALUE |+-------------------+----------------+| HANDLER_READ_NEXT | 11111 | #請求讀的行數| INNODB_DATA_READS | 7868409 | #數據物理讀的總數| INNODB_PAGES_READ | 7855239 | #邏輯讀的總數| LAST_QUERY_COST | 10.499000 | #SQL語句的成本COST,主要包括IO_COST和CPU_COST。+-------------------+----------------+4 rows in set (0.00 sec)刪除后的SQL執行情況

#刪除50w數據mysql> delete from user limit 500000;Query OK, 500000 rows affected (3.70 sec)#分析表統計信息mysql> analyze table user;+-----------+---------+----------+----------+| Table | Op | Msg_type | Msg_text |+-----------+---------+----------+----------+| test.user | analyze | status | OK |+-----------+---------+----------+----------+1 row in set (0.01 sec)#重置狀態變量計數mysql> flush status;Query OK, 0 rows affected (0.01 sec)mysql> select id, age ,phone from user where name like ’lyn12%’;Empty set (0.05 sec)mysql> explain select id, age ,phone from user where name like ’lyn12%’;+----+-------------+-------+-------+---------------+----------+---------+------+-------+-----------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+-------+---------------+----------+---------+------+-------+-----------------------+| 1 | SIMPLE | user | range | idx_name | idx_name | 82 | NULL | 22226 | Using index condition |+----+-------------+-------+-------+---------------+----------+---------+------+-------+-----------------------+1 row in set (0.00 sec)mysql> select * from information_schema.session_status where variable_name in(’Last_query_cost’,’Handler_read_next’,’Innodb_pages_read’,’Innodb_data_reads’,’Innodb_pages_read’);+-------------------+----------------+| VARIABLE_NAME | VARIABLE_VALUE |+-------------------+----------------+| HANDLER_READ_NEXT | 0 || INNODB_DATA_READS | 7868409 || INNODB_PAGES_READ | 7855239 || LAST_QUERY_COST | 10.499000 |+-------------------+----------------+4 rows in set (0.00 sec)

結果統計分析

操作 COST 物理讀次數 邏輯讀次數 掃描行數 返回行數 執行時間 初始化插入100W 10.499000 7868409 7855239 22226 11111 30ms 100W隨機刪除50W 10.499000 7868409 7855239 22226 0 50ms

這也說明對普通的大表,想要通過delete數據來對表進行瘦身是不現實的,所以在任何時候不要用delete去刪除數據,應該使用優雅的標記刪除。

delete優化建議控制業務賬號權限

對于一個大的系統來說,需要根據業務特點去拆分子系統,每個子系統可以看做是一個service,例如美團APP,上面有很多服務,核心的服務有用戶服務user-service,搜索服務search-service,商品product-service,位置服務location-service,價格服務price-service等。每個服務對應一個數據庫,為該數據庫創建單獨賬號,同時只授予DML權限且沒有delete權限,同時禁止跨庫訪問。

#創建用戶數據庫并授權create database mt_user charset utf8mb4;grant USAGE, SELECT, INSERT, UPDATE ON mt_user.* to ’w_user’@’%’ identified by ’t$W*g@gaHTGi123456’;flush privileges;delete改為標記刪除

在MySQL數據庫建模規范中有4個公共字段,基本上每個表必須有的,同時在create_time列要創建索引,有兩方面的好處:

一些查詢業務場景都會有一個默認的時間段,比如7天或者一個月,都是通過create_time去過濾,走索引掃描更快。 一些核心的業務表需要以T +1的方式抽取數據倉庫中,比如每天晚上00:30抽取前一天的數據,都是通過create_time過濾的。

`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ’主鍵id’,`is_deleted` tinyint(4) NOT NULL DEFAULT ’0’ COMMENT ’是否邏輯刪除:0:未刪除,1:已刪除’,`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ’創建時間’,`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ’修改時間’#有了刪除標記,業務接口的delete操作就可以轉換為updateupdate user set is_deleted = 1 where user_id = 1213;#查詢的時候需要帶上is_deleted過濾select id, age ,phone from user where is_deleted = 0 and name like ’lyn12%’;數據歸檔方式通用數據歸檔方法

#1. 創建歸檔表,一般在原表名后面添加_bak。CREATE TABLE `ota_order_bak` ( `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT ’主鍵’, `order_id` varchar(255) DEFAULT NULL COMMENT ’訂單id’, `ota_id` varchar(255) DEFAULT NULL COMMENT ’ota’, `check_in_date` varchar(255) DEFAULT NULL COMMENT ’入住日期’, `check_out_date` varchar(255) DEFAULT NULL COMMENT ’離店日期’, `hotel_id` varchar(255) DEFAULT NULL COMMENT ’酒店ID’, `guest_name` varchar(255) DEFAULT NULL COMMENT ’顧客’, `purcharse_time` timestamp NULL DEFAULT NULL COMMENT ’購買時間’, `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, `create_user` varchar(255) DEFAULT NULL, `update_user` varchar(255) DEFAULT NULL, `status` int(4) DEFAULT ’1’ COMMENT ’狀態 : 1 正常 , 0 刪除’, `hotel_name` varchar(255) DEFAULT NULL, `price` decimal(10,0) DEFAULT NULL, `remark` longtext, PRIMARY KEY (`id`), KEY `IDX_order_id` (`order_id`) USING BTREE, KEY `hotel_name` (`hotel_name`) USING BTREE, KEY `ota_id` (`ota_id`) USING BTREE, KEY `IDX_purcharse_time` (`purcharse_time`) USING BTREE, KEY `IDX_create_time` (`create_time`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8PARTITION BY RANGE (to_days(create_time)) ( PARTITION p201808 VALUES LESS THAN (to_days(’2018-09-01’)), PARTITION p201809 VALUES LESS THAN (to_days(’2018-10-01’)), PARTITION p201810 VALUES LESS THAN (to_days(’2018-11-01’)), PARTITION p201811 VALUES LESS THAN (to_days(’2018-12-01’)), PARTITION p201812 VALUES LESS THAN (to_days(’2019-01-01’)), PARTITION p201901 VALUES LESS THAN (to_days(’2019-02-01’)), PARTITION p201902 VALUES LESS THAN (to_days(’2019-03-01’)), PARTITION p201903 VALUES LESS THAN (to_days(’2019-04-01’)), PARTITION p201904 VALUES LESS THAN (to_days(’2019-05-01’)), PARTITION p201905 VALUES LESS THAN (to_days(’2019-06-01’)), PARTITION p201906 VALUES LESS THAN (to_days(’2019-07-01’)), PARTITION p201907 VALUES LESS THAN (to_days(’2019-08-01’)), PARTITION p201908 VALUES LESS THAN (to_days(’2019-09-01’)), PARTITION p201909 VALUES LESS THAN (to_days(’2019-10-01’)), PARTITION p201910 VALUES LESS THAN (to_days(’2019-11-01’)), PARTITION p201911 VALUES LESS THAN (to_days(’2019-12-01’)), PARTITION p201912 VALUES LESS THAN (to_days(’2020-01-01’)));#2. 插入原表中無效的數據(需要跟開發同學確認數據保留范圍)create table tbl_p201808 as select * from ota_order where create_time between ’2018-08-01 00:00:00’ and ’2018-08-31 23:59:59’;#3. 跟歸檔表分區做分區交換alter table ota_order_bak exchange partition p201808 with table tbl_p201808;#4. 刪除原表中已經規范的數據delete from ota_order where create_time between ’2018-08-01 00:00:00’ and ’2018-08-31 23:59:59’ limit 3000;優化后的歸檔方式

#1. 創建中間表CREATE TABLE `ota_order_2020` (........) ENGINE=InnoDB DEFAULT CHARSET=utf8PARTITION BY RANGE (to_days(create_time)) ( PARTITION p201808 VALUES LESS THAN (to_days(’2018-09-01’)), PARTITION p201809 VALUES LESS THAN (to_days(’2018-10-01’)), PARTITION p201810 VALUES LESS THAN (to_days(’2018-11-01’)), PARTITION p201811 VALUES LESS THAN (to_days(’2018-12-01’)), PARTITION p201812 VALUES LESS THAN (to_days(’2019-01-01’)), PARTITION p201901 VALUES LESS THAN (to_days(’2019-02-01’)), PARTITION p201902 VALUES LESS THAN (to_days(’2019-03-01’)), PARTITION p201903 VALUES LESS THAN (to_days(’2019-04-01’)), PARTITION p201904 VALUES LESS THAN (to_days(’2019-05-01’)), PARTITION p201905 VALUES LESS THAN (to_days(’2019-06-01’)), PARTITION p201906 VALUES LESS THAN (to_days(’2019-07-01’)), PARTITION p201907 VALUES LESS THAN (to_days(’2019-08-01’)), PARTITION p201908 VALUES LESS THAN (to_days(’2019-09-01’)), PARTITION p201909 VALUES LESS THAN (to_days(’2019-10-01’)), PARTITION p201910 VALUES LESS THAN (to_days(’2019-11-01’)), PARTITION p201911 VALUES LESS THAN (to_days(’2019-12-01’)), PARTITION p201912 VALUES LESS THAN (to_days(’2020-01-01’)));#2. 插入原表中有效的數據,如果數據量在100W左右可以在業務低峰期直接插入,如果比較大,建議采用dataX來做,可以控制頻率和大小,之前我這邊用Go封裝了dataX可以實現自動生成json文件,自定義大小去執行。insert into ota_order_2020 select * from ota_order where create_time between ’2020-08-01 00:00:00’ and ’2020-08-31 23:59:59’;#3. 表重命名alter table ota_order rename to ota_order_bak; alter table ota_order_2020 rename to ota_order;#4. 插入差異數據insert into ota_order select * from ota_order_bak a where not exists (select 1 from ota_order b where a.id = b.id);#5. ota_order_bak改造成分區表,如果表比較大不建議直接改造,可以先創建好分區表,通過dataX把導入進去即可。#6. 后續的歸檔方法#創建中間普遍表create table ota_order_mid like ota_order;#交換原表無效數據分區到普通表alter table ota_order exchange partition p201808 with table ota_order_mid; ##交換普通表數據到歸檔表的相應分區alter table ota_order_bak exchange partition p201808 with table ota_order_mid;

這樣原表和歸檔表都是按月的分區表,只需要創建一個中間普通表,在業務低峰期做兩次分區交換,既可以刪除無效數據,又能回收空,而且沒有空間碎片,不會影響表上的索引及SQL的執行計劃。

總結

通過從InnoDB存儲空間分布,delete對性能的影響可以看到,delete物理刪除既不能釋放磁盤空間,而且會產生大量的碎片,導致索引頻繁分裂,影響SQL執行計劃的穩定性;

同時在碎片回收時,會耗用大量的CPU,磁盤空間,影響表上正常的DML操作。

在業務代碼層面,應該做邏輯標記刪除,避免物理刪除;為了實現數據歸檔需求,可以用采用MySQL分區表特性來實現,都是DDL操作,沒有碎片產生。

另外一個比較好的方案采用Clickhouse,對有生命周期的數據表可以使用Clickhouse存儲,利用其TTL特性實現無效數據自動清理。

到此這篇關于淺談為什么MySQL不建議delete刪除數據的文章就介紹到這了,更多相關MySQL不建議delete刪除內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: MySQL 數據庫
相關文章:
主站蜘蛛池模板: 日韩视频在线免费观看 | 成人欧美一区二区三区视频xxx | 久久精品日 | 日产精品久久久一区二区 | 亚洲第一av | 日本免费一区二区三区 | 91国在线高清视频 | 欧美成人精品一区二区男人看 | 日韩大尺度在线观看 | 成年人精品视频在线观看 | 午夜影院在线 | 免费观看电视在线高清视频 | 中文字幕亚洲一区 | youjizz欧美 | 一级片在线免费看 | 久久久99国产精品免费 | 一区二区在线看 | 青青久在线视频 | 精品国产三级a在线观看 | www.久久.com| 久久一| 国产精品久久久久久久久久 | 中文字幕在线观看av | 日韩素人在线 | 欧美在线免费 | 成人老司机 | 91精品久久久久久 | 91av免费在线观看 | 精品护士一区二区三区 | 久久久久久久一区 | 久久激情视频 | 美女91 | 成年入口无限观看网站 | www操com| 在线观看成人 | 亚洲一区电影 | 久草视频在线播放 | 午夜影院在线观看 | 欧美成人性生活视频 | 亚洲视频成人 | 中文字幕日韩在线 | 亚洲精品国产高清 | 国产精品成人国产乱一区 | 久久99精品国产麻豆婷婷洗澡 | 欧美激情一区二区三区 | 久久精品一区二区三区四区 | 日韩在线字幕 | 日韩精品在线视频 | 91性高湖久久久久久久久网站 | 亚洲国产成人在线视频 | 日韩在线免费电影 | 中文字幕在线免费 | 亚洲欧美激情精品一区二区 | 日韩毛片免费在线观看 | 最新的黄色网址 | 久久久久久久一区 | 国产精品久久久久久久久免费 | 欧美一区二区三区在线观看 | 亚洲国产成人在线 | 夜夜操导航 | 日韩成人在线观看 | 亚洲视频1 | 国产超碰人人爽人人做人人爱 | 国产精品99久久免费观看 | 欧美激情在线精品一区二区三区 | 国产艳妇av视国产精选av一区 | 欧美国产精品 | 久草日韩 | 国产日韩在线播放 | 一级a性色生活片毛片 | 亚洲国产成人91精品 | 欧美一区永久视频免费观看 | 日本精品在线播放 | 少妇激烈床戏视频 | 在线观看免费av的网址 | 国变精品美女久久久久av爽 | 中文精品一区二区三区 | 台湾av在线| 国产精品一区二区三区在线播放 | 国产视频久久 | 久久婷婷麻豆国产91天堂 | 中文字幕一区二区三区四区 | 久久久91精品国产一区二区精品 | 久久精品a一级国产免视看成人 | 亚洲成人av一区二区 | 国产精品成av人在线视午夜片 | 一区二区三区在线看 | 亚洲国产一区二区三区四区 | 亚洲综合无码一区二区 | 国产精品久久久久久久免费大片 | 一区二区三区在线播放 | 成人精品一区二区三区 | 国产区在线观看 | 欧美日韩一| 国产精品1区2区3区 欧美 中文字幕 | 一级毛片免费视频 | 在线观看亚洲大片短视频 | 无码日韩精品一区二区免费 | 亚洲国产日韩a在线播放性色 | 久久99精品国产麻豆婷婷洗澡 | 午夜成人在线视频 | 国产精品香蕉在线观看 | 一级毛片一级毛片一级毛片 | 日韩欧美国产精品一区二区三区 | 久久久久久精 | 在线免费毛片 | 精品视频久久久 | 国产97人人超碰caoprom | 欧美日韩精品一区二区 | 久久久av | 国产亚洲精品v | 黄网站色大毛片 | 韩国精品一区 | 亚洲伊人久久综合 | 欧美在线影院 | 国产v日产∨综合v精品视频 | 国产xxxxxxxxxx| 日韩在线免费观看视频 | 国产成人精品免费视频大全 | 日韩欧美高清dvd碟片 | 亚洲成人免费在线 | 亚洲免费在线观看 | 91在线免费看 | 国产成人精品一区二区三区视频 | 亚洲人免费| 一区二区三区在线 | 欧 | 中文字幕精品三级久久久 | hd国产人妖ts另类视频 | 中文字幕日韩一区二区 | 日本一区二区成人 | 国产精品第52页 | 免费在线观看国产 | 国产男人天堂 | 91在线视频 | 色视频在线免费观看 | 三级黄色片在线播放 | 久久大陆| 国产综合视频在线观看 | 日韩精品一区二区三区在线观看 | 欧洲视频一区二区 | 久久久高清| 成人高清视频在线 | 久久99操| 国产综合久久久久久鬼色 | 日韩不卡一区二区 | 国产欧美一区二区精品忘忧草 | 日韩中文字幕一区二区高清99 | caoporn视频| 91色爱| 国产精品毛片久久久久久久 | 亚洲人网站 | 国产精品国产三级国产aⅴ9色 | 视频一区二区中文字幕 | 亚洲网在线| 成人不卡| 久久精品黄 | av大片在线观看 | av观看在线 | 密室大逃脱第六季大神版在线观看 | 久久久国产精品入口麻豆 | 国产人免费人成免费视频 | 成人亚洲 | 91久久久久久久久 | 午夜久久av | 午夜精品久久久久久久久久久久久 | 亚洲不卡| 成人久久久久久久 | www.一区 | 国产一区二区在线看 | 99久久久国产精品美女 | 在线观看黄色大片 | 精品国产一区二区三区性色av | 91久久精品久久国产性色也91 | 在线看一区 | 欧美日韩视频在线观看一区 | 亚洲一区中文字幕在线观看 | www.视频在线观看 | 性免费网站 | 另类五月 | 精品一区免费 | 看片一区 | 欧美久热 | 亚洲一区二区三区高清 | 蜜臀影院 | 国产精品成人国产乱一区 | 91免费影片 | 国产午夜精品久久久 | 精久视频 | 就操成人网 | 精品美女在线观看视频在线观看 | 日韩免费在线观看视频 | 中文字幕一区在线观看视频 | 欧美一区二区三区精品 | 精品综合久久 | 蜜桃一区二区三区 | 亚洲不卡视频 | 亚洲成人在线视频播放 | 在线亚洲一区二区 | 亚洲 欧美 精品 | 日韩精品一区二区三区在线 | 九九热在线免费视频 | 91视频久久 | 欧美日韩一级二级三级 | 色综合一区二区三区 | 久久久精品日韩 | 中文字幕在线看第二 | 中文字幕av亚洲精品一部二部 | a中文在线视频 | 欧美日本久久 | 成人免费毛片aaaaaa片 | 久久99视频 | 精品一区二区免费视频 | 97伦理电影院| 免费一级在线观看 | av三级在线免费观看 | 国产精品热 | 激情欧美一区二区三区中文字幕 | 韩日中文字幕 | 7777久久| 国产精品久久天天躁 | 久久久一区二区 | 一色桃子av一区二区免费 | 99re视频精品| 国产精品毛片久久久久久久 | 91精品国产综合久久久久久蜜月 | 亚洲精品视频在线播放 | 精品一区二区三区免费毛片爱 | 精品二区 | 欧美精品成人一区二区在线 | 国产精品无码久久久久 | 国产一区高清 | 亚洲一区二区三区高清 | 99精品欧美一区二区蜜桃免费 | 欧美成人一区二免费视频软件 | 91影院 | 国产成人精品一区二 | 成人在线 | 国产亚洲视频在线 | 成人观看免费视频 | 自拍视频在线播放 | 成人毛片在线视频 | 日韩一区二区三区在线观看 | 国产九九精品视频 | 亚洲电影二区 | 日本久久久久久 | 亚洲aⅴ网站| 国产精品久久久久久久久岛 | 欧美一级黄色片网站 | 五月天婷婷色综合 | 欧美一级片在线 | 一区二区电影 | 91社区在线观看高清 | 国产精品夜夜爽 | 精品亚洲成人 | 午夜视频 | aaa久久 | 亚洲 欧美 自拍偷拍 | 亚洲高清视频一区二区三区 | 欧美区国产区 | 99热在线免费观看 | 日韩一级免费在线观看 | 在线国产一区二区 | 亚洲视频在线观看免费 | 国产野精品久久久久久久不卡 | 黄色一级大片在线免费看产 | 久久综合一区二区三区 | 欧美日韩中文字幕 | 四虎影院在线免费播放 | 中文日韩在线 | 精品一区二区在线观看 | 免费在线日本 | 中文字幕一区在线观看 | 一区二区三区视频在线播放 | 最新中文字幕 | 国产成人精品一区二 | 精品在线视频一区 | 免费观看羞羞视频网站 | 欧美亚洲视频在线观看 | 久草视 | 亚洲国产精品精华液网站 | a在线观看 | 奇米色777欧美一区二区 | 国产区最新 | 国产成人精品999在线观看 | 午夜免费福利视频 | 国产三区在线成人av | 亚洲国产高清视频 | 九色网址 | 中国特级黄色片 | 午夜国产一级 | 99亚洲国产精品 | 精品国产一区二区三区日日嗨 | 午夜精品久久久久久久白皮肤 | 日韩视频一区二区三区 | 夜夜夜久久久 | 日韩一区二区在线播放 | 午夜在线 | 日本五月婷婷 | av一区二区在线观看 | 成人欧美一区二区三区 | 欧美精品免费在线观看 | 国产在线视频网站 | av观看在线| 精品一区二区av | 精品一区二区三区三区 | 精品日韩欧美一区二区三区在线播放 | 成人免费网站www网站高清 | 综合五月网 | 国产情侣av自拍 | 成人在线视频网站 | 中文成人在线 | 高清久久| 国产精品久久久久久久久久久久久 | 日韩免费片 | 亚洲网站在线观看 | 久草热8精品视频在线观看 黄色片网站视频 | 国产一区二区视频在线播放 | 日韩美一级| 国产极品视频在线观看 | 精品久久久久久久 | 国产午夜视频在线观看 | 91久久久久久久久久久久久久久久 | 不卡一区二区三区视频 | 国产精品视频一区二区三区四蜜臂 | 羞羞视频在线观看免费 | 日一区二区 | 亚洲免费a| 91中文在线观看 | 成人免费在线观看 | 在线免费观看日韩视频 | 天天插天天射天天干 | 国产一区二区三区久久久 | 91精品国产99 | 亚洲精选久久久 | 免费欧美一级 | 日韩欧美国产一区二区 | 9uu在线观看 | 亚洲人免费视频 | 超碰最新在线 | 成人国产 | 中文二区| 中文字幕亚洲字幕一区二区 | 亚洲视频在线播放 | 午夜精品久久久久99蜜 | 青草视频网站 | 精品久久久久久久久久久久久久 | 日韩精品在线观看视频 | 久久久久综合 | 中文字幕91 | 色播久久久| 草久在线视频 | 亚洲狠狠久久综合一区77777 | 久久三区| 在线观看成人小视频 | 色婷婷综合久久久中字幕精品久久 | 午夜免费一区二区播放 | 永久免费精品视频 | 婷婷亚洲综合 | 欧美亚洲天堂 | 日韩欧美在线视频观看 | 天天av网 | 久久久国产视频 | 中文字幕在线不卡 | 青草青草久热精品视频在线观看 | 国产中文字幕一区 | 久久99国产精一区二区三区 | 欧美一区二区免费 | 一区二区三区免费看 | 91精品一区二区 | 国产一级在线观看 | 精品无码久久久久久国产 | 91精品入口蜜桃 | 欧美顶级毛片在线播放 | 性大毛片视频 | 国产一级特黄aaa大片 | 久在线视频播放免费视频 | 欧美第一视频 | 久久777| 国产精品久久久久久久久久久久冷 | 欧洲一区二区三区 | 日本 欧美 三级 高清 视频 | 国产麻豆乱码精品一区二区三区 | 天天干天天操天天爽 | 亚洲aⅴ | 午夜影院a | 欧美福利电影在线观看 | 999视频在线 | 久久精品视频一区 | 美女视频一区二区三区 | 日韩中文字幕一区 | 91在线播放视频 | 日韩免费观看视频 | 国产91在线观看 | 91中文| 亚洲精品国产乱码在线看蜜月 | 福利视频网址导航 | 国产成人av一区二区 | 国产精久久一区二区三区 | 欧美日韩一区二区三区不卡视频 | 一区二区三区不卡视频 | 在线成人| 国产在线观看一区二区 | 一级黄免费看 | 五月天婷婷激情视频 | 精品一区二区三区四区视频 | 亚洲欧美综合一区 | 欧美乱码久久久久久蜜桃 | 国产精品久久久久毛片软件 | t66y最新地址一地址二69 | 中文一区 | 亚洲精品一区在线观看 | 午夜视频在线观看网站 | 99这里只有精品视频 | 精产国产伦理一二三区 | а天堂中文最新一区二区三区 | 国产精品中文字幕在线播放 | 黄色av免费看 | 久久激情视频 | 欧美电影一区 | 国产专区在线视频 | 久久精品免费视频观看 | 伊人av在线免费观看 | 国产成人精品久久二区二区 | 伊人电影综合网 | 久久久国产精品 | 精品一区二区三区国产 | 欧美精品一区自拍a毛片在线视频 | 欧美日韩精品久久久久 | 欧美日韩综合精品 | 国产大片久久久 | 一区自拍 | 狠狠操电影| 91精品国产综合久久久久久蜜月 | 久草综合网 | 国产精品二区三区在线观看 | 国产精品久久 | 欧美精品在线一区 | av免费在线播放 | 欧美一区二区三区男人的天堂 | 午夜影视 | 性色av一二三杏吧传媒 | 午夜高清视频 | 国产欧美日韩综合精品一区二区 | 欧美精品一区二区在线观看 | 免费视频一区 | 中文在线资源 | 在线观看国产精品一区 | 综合99| 在线视频亚洲 | 99国产精品久久久 | 亚洲二区在线播放 | 日本高清中文字幕 | 黄色在线免费看 | 欧美精品综合 | 中文字幕在线观看1 | 性视频黄色 | 久久久久久久久一区 | 久久久久国产精品 | 成人不卡视频 | 午夜家庭影院 | 91婷婷射 | 亚洲 欧美日韩 国产 中文 | 欧美一区永久视频免费观看 | 狠狠狠 | 日本精a在线观看 | 国产精品免费一区二区三区四区 | 99热在线播放| 第一色站 | 99精品99| 欧美日韩一区二区三区在线电影 | 欧美日韩在线一区 | 欧美一区二区三区aa大片漫 | 精品一区不卡 | 午夜av影院 | 超级碰在线视频 | 欧美精品二区中文乱码字幕高清 | 日韩av手机在线免费观看 | 成人亚洲视频 | 欧美日韩一区二区电影 | 色婷婷综合久久 | 91看片淫黄大片一级在线观看 | 日韩在线精品视频 | 激情毛片| 伊人网在线免费观看 | 精品一区二区视频 | 正在播放国产一区 | 日韩精品专区在线影院重磅 | 国产高清在线精品一区二区三区 | 一区自拍| 国产精品毛片久久久久久 | 黄片毛片在线观看 | av中文字幕在线播放 | 激情.com| 久久亚洲综合 | 日日干,天天干 | 毛片福利 | 欧美精品一区二区三区蜜桃视频 | 久久国产精品免费一区二区三区 | 人人干人人干人人 | 狠狠干干 | 91精品久久久久久久久久入口 | 精品国产仑片一区二区三区 | 一级黄色毛片免费 | 成人高清视频免费观看 | 久久社区 | 亚洲污视频 | 日日骚视频 | 伊人色播 | 亚洲一区视频 | 亚州av在线 | 中文字幕av第一页 | 亚洲精品www久久久久久 | 中文字幕在线观看 | 香蕉成人啪国产精品视频综合网 | 午夜精品久久久久久久久久久久 | 欧洲毛片基地 | 成人精品视频一区二区三区 | 可以免费在线观看av的网站 | 久久精品这里热有精品 | 久久伦理电影网 | 自拍偷拍第一页 | 99亚洲精品 | 一级片网 | 曰批免费视频播放免费 | 精品三区在线观看 | 国产在线二区 | 黄色免费网站观看 | 精品精品 | 2019中文字幕视频 | 亚洲欧美日韩在线 | 久久综合久久久 | 国产在线播 | 一区免费视频 | 日韩成人中文字幕 | 日韩av福利 | 成人免费在线 | 国产精品美女 | 日韩一区高清视频 | 久久中文视频 | 国产大毛片 | √天堂在线 | 羞羞视频在线免费 | 天天天堂 | 日韩欧美在线视频 | 天天插天天射天天干 | 深夜成人小视频 | 国产视频9999 | a黄视频 | 日本aⅴ毛片成人实战推荐 成人免毛片 | 亚洲午夜视频 | 精品视频久久 | av一区在线观看 | 欧美成人黑人xx视频免费观看 | 日本二区在线观看 | 99精品欧美一区二区三区综合在线 | 日本久久久影视 | 精品亚洲精品 | 色婷婷综合网 | 欲色av| 免费成人av| 国产精品精品视频一区二区三区 | 久久com| 欧美二三区 | 国产成人精品一区二区 | 亚洲色域网 | 天天看天天摸天天操 | 宅男伊人 | 国产精品久久久久久亚洲调教 | 国产精品国产三级国产aⅴ原创 | 黄色在线免费观看 | 午夜爽爽影院 | 国产精品成人一区二区三区夜夜夜 | 在线a视频 | 夜夜av| 成人福利在线 | av网站免费观看 | 久爱国产 | 毛片免费观看网址 | 国产成人啪精品午夜在线观看 | 欧美黄色一区二区 | 一区二区三区高清不卡 | 日韩福利视频 | 华丽的挑战在线观看 | 久草视频在线播放 | 日韩视频中文字幕 | 91精品久久 | 99re视频 | 日本亚洲国产一区二区三区 | 午夜播影院 | 日韩国产在线观看 | 91一区二区| 台湾av在线 | 国产999免费视频 | 久久永久视频 | 久久av一区二区三区 | 一级特黄网站 | 中文字幕高清视频 | 久久九九视频 | 天天艹久久 | 国产网站在线播放 | 欧美日韩中文在线观看 | 中文字幕日韩在线 | 亚洲不卡视频在线观看 | 日日夜夜精品 | 性视频一区二区 | 久久久男人天堂 | 在线精品亚洲欧美日韩国产 | 超级黄色一级片 | 日韩一级免费在线观看 | 91麻豆精品国产91久久久更新资源速度超快 | 天堂va在线高清一区 | 成人av免费在线观看 | 国产在线观看一区二区三区 | 成人九色| 久久久久亚洲一区二区三区 |