如果觉得文章有用,欢迎关注❤️、点赞👍、推荐🎁
批量更新和删除,减少锁资源的争用,限制对系统的影响。
减少数据文件和重做日志磁盘的使用。
分区之间的批量数据迁移。
CREATE TABLE big_table (id INT PRIMARY KEY, v VARCHAR(10));
WITH RECURSIVE d(n) AS (
SELECT 1
UNION ALL
SELECT n + 1 FROM d WHERE n < 100000
)
INSERT INTO big_table
SELECT n, concat('id:', n) FROM d;
SELECT * FROM big_table ORDER BY id LIMIT 10;
id|v |
--+-----+
1|id:1 |
2|id:2 |
3|id:3 |
4|id:4 |
5|id:5 |
6|id:6 |
7|id:7 |
8|id:8 |
9|id:9 |
10|id:10|
WITH deleted_rows AS (
SELECT id
FROM big_table
LIMIT 10
)
DELETE FROM big_table
WHERE id IN (SELECT id FROM deleted_rows);
EXPLAIN
WITH deleted_rows AS (
SELECT id
FROM big_table
LIMIT 10
)
DELETE FROM big_table
WHERE id IN (SELECT id FROM deleted_rows);
QUERY PLAN |
---------------------------------------------------------------------------------------------------------+
Delete on big_table (cost=0.57..83.48 rows=0 width=0) |
-> Nested Loop (cost=0.57..83.48 rows=10 width=34) |
-> HashAggregate (cost=0.28..0.38 rows=10 width=32) |
Group Key: deleted_rows.id |
-> Subquery Scan on deleted_rows (cost=0.00..0.25 rows=10 width=32) |
-> Limit (cost=0.00..0.15 rows=10 width=4) |
-> Seq Scan on big_table big_table_1 (cost=0.00..1541.00 rows=100000 width=4)|
-> Index Scan using big_table_pkey on big_table (cost=0.29..8.31 rows=1 width=10) |
Index Cond: (id = deleted_rows.id) |
EXPLAIN
WITH deleted_rows AS (
SELECT id
FROM big_table
LIMIT 10
)
DELETE FROM big_table
WHERE EXISTS (SELECT * FROM deleted_rows d WHERE d.id = big_table.id);
QUERY PLAN |
---------------------------------------------------------------------------------------------------------+
Delete on big_table (cost=0.57..83.48 rows=0 width=0) |
-> Nested Loop (cost=0.57..83.48 rows=10 width=34) |
-> HashAggregate (cost=0.28..0.38 rows=10 width=32) |
Group Key: d.id |
-> Subquery Scan on d (cost=0.00..0.25 rows=10 width=32) |
-> Limit (cost=0.00..0.15 rows=10 width=4) |
-> Seq Scan on big_table big_table_1 (cost=0.00..1541.00 rows=100000 width=4)|
-> Index Scan using big_table_pkey on big_table (cost=0.29..8.31 rows=1 width=10) |
Index Cond: (id = d.id) |
EXPLAIN
WITH deleted_rows AS (
SELECT id
FROM big_table
ORDER BY id
LIMIT 10
)
DELETE FROM big_table
WHERE id IN (SELECT id FROM deleted_rows);
QUERY PLAN |
-------------------------------------------------------------------------------------------------------------------------------------+
Delete on big_table (cost=0.97..83.88 rows=0 width=0) |
-> Nested Loop (cost=0.97..83.88 rows=10 width=34) |
-> HashAggregate (cost=0.68..0.78 rows=10 width=32) |
Group Key: deleted_rows.id |
-> Subquery Scan on deleted_rows (cost=0.29..0.65 rows=10 width=32) |
-> Limit (cost=0.29..0.55 rows=10 width=4) |
-> Index Only Scan using big_table_pkey on big_table big_table_1 (cost=0.29..2604.29 rows=100000 width=4)|
-> Index Scan using big_table_pkey on big_table (cost=0.29..8.31 rows=1 width=10) |
Index Cond: (id = deleted_rows.id) |
EXPLAIN ANALYZE
WITH updated_rows AS (
SELECT id
FROM big_table
ORDER BY id
LIMIT 10
)
UPDATE big_table
SET v = 'new value'
WHERE EXISTS (SELECT * FROM updated_rows d WHERE d.id = big_table.id);
QUERY PLAN |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Update on big_table (cost=0.97..83.88 rows=0 width=0) (actual time=0.586..0.587 rows=0 loops=1) |
-> Nested Loop (cost=0.97..83.88 rows=10 width=72) (actual time=0.056..0.078 rows=10 loops=1) |
-> HashAggregate (cost=0.68..0.78 rows=10 width=32) (actual time=0.044..0.048 rows=10 loops=1) |
Group Key: d.id |
Batches: 1 Memory Usage: 24kB |
-> Subquery Scan on d (cost=0.29..0.65 rows=10 width=32) (actual time=0.034..0.038 rows=10 loops=1) |
-> Limit (cost=0.29..0.55 rows=10 width=4) (actual time=0.019..0.021 rows=10 loops=1) |
-> Index Only Scan using big_table_pkey on big_table big_table_1 (cost=0.29..2604.29 rows=100000 width=4) (actual time=0.018..0.019 rows=10 loops=1)|
Heap Fetches: 0 |
-> Index Scan using big_table_pkey on big_table (cost=0.29..8.31 rows=1 width=10) (actual time=0.002..0.002 rows=1 loops=10) |
Index Cond: (id = d.id) |
Planning Time: 0.232 ms |
Execution Time: 0.641 ms |
SELECT COUNT(*)
FROM big_table
WHERE v = 'new value';
count|
-----+
10|
EXPLAIN ANALYZE
WITH updated_rows AS (
SELECT id
FROM big_table
ORDER BY random()
LIMIT 10
)
UPDATE big_table
SET v = 'new value'
WHERE EXISTS (SELECT * FROM updated_rows d WHERE d.id = big_table.id);
QUERY PLAN |
------------------------------------------------------------------------------------------------------------------------------------------------+
Update on big_table (cost=3952.51..4035.42 rows=0 width=0) (actual time=49.711..49.713 rows=0 loops=1) |
CTE updated_rows |
-> Limit (cost=3951.96..3951.99 rows=10 width=12) (actual time=49.438..49.441 rows=10 loops=1) |
-> Sort (cost=3951.96..4201.96 rows=100000 width=12) (actual time=49.433..49.434 rows=10 loops=1) |
Sort Key: (random()) |
Sort Method: top-N heapsort Memory: 25kB |
-> Seq Scan on big_table big_table_1 (cost=0.00..1791.00 rows=100000 width=12) (actual time=0.034..29.596 rows=100000 loops=1)|
-> Nested Loop (cost=0.52..83.43 rows=10 width=72) (actual time=49.493..49.534 rows=10 loops=1) |
-> HashAggregate (cost=0.23..0.33 rows=10 width=32) (actual time=49.462..49.465 rows=10 loops=1) |
Group Key: d.id |
Batches: 1 Memory Usage: 24kB |
-> CTE Scan on updated_rows d (cost=0.00..0.20 rows=10 width=32) (actual time=49.446..49.453 rows=10 loops=1) |
-> Index Scan using big_table_pkey on big_table (cost=0.29..8.31 rows=1 width=10) (actual time=0.006..0.006 rows=1 loops=10) |
Index Cond: (id = d.id) |
Planning Time: 0.333 ms |
Execution Time: 49.820 ms |
EXPLAIN ANALYZE
WITH updated_rows AS (
SELECT id
FROM big_table
ORDER BY v
LIMIT 10
)
UPDATE big_table
SET v = 'new value'
WHERE EXISTS (SELECT * FROM updated_rows d WHERE d.id = big_table.id);
QUERY PLAN |
---------------------------------------------------------------------------------------------------------------------------------------------------------------+
Update on big_table (cost=3702.21..5505.83 rows=0 width=0) (actual time=88.642..88.647 rows=0 loops=1) |
-> Hash Semi Join (cost=3702.21..5505.83 rows=10 width=72) (actual time=19.764..41.442 rows=10 loops=1) |
Hash Cond: (big_table.id = d.id) |
-> Seq Scan on big_table (cost=0.00..1541.00 rows=100000 width=10) (actual time=0.044..13.495 rows=100000 loops=1) |
-> Hash (cost=3702.09..3702.09 rows=10 width=32) (actual time=19.652..19.656 rows=10 loops=1) |
Buckets: 1024 Batches: 1 Memory Usage: 9kB |
-> Subquery Scan on d (cost=3701.96..3702.09 rows=10 width=32) (actual time=19.629..19.641 rows=10 loops=1) |
-> Limit (cost=3701.96..3701.99 rows=10 width=12) (actual time=19.602..19.605 rows=10 loops=1) |
-> Sort (cost=3701.96..3951.96 rows=100000 width=12) (actual time=19.601..19.602 rows=10 loops=1) |
Sort Key: big_table_1.v |
Sort Method: top-N heapsort Memory: 25kB |
-> Seq Scan on big_table big_table_1 (cost=0.00..1541.00 rows=100000 width=12) (actual time=0.020..8.034 rows=100000 loops=1)|
Planning Time: 0.232 ms |
Execution Time: 88.712 ms |
原文作者:SQL编程思想;如有侵权,请联系管理员删除。