VACUUM ба ANALYZE
PostgreSQL-д мөр DELETE хийгдэх эсвэл UPDATE болоход тухайн мөр дискнээс шууд устдаггүй — dead tuple буюу "үхсэн мөр" болж хэвээр үлддэг. Шинэ transaction бүр хуучин хувилбарыг харах шаардлагатай байж болох учраас энэ зориудын шийдэл юм (MVCC). Гэвч цаг хугацаа өнгөрөх тусам эдгээр dead tuple хуримтлагдаж дискний зай эзэлнэ. VACUUM нь тэдгээрийг цэвэрлэдэг.
Dead tuple гэж юу вэ?
-- Жишээ хүснэгт
CREATE TABLE events (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
status TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
INSERT INTO events (name, status)
SELECT 'Арга хэмжээ ' || i, 'active'
FROM GENERATE_SERIES(1, 10000) AS i;
-- Dead tuple үүсгэх
UPDATE events SET status = 'archived' WHERE id <= 5000;
DELETE FROM events WHERE id BETWEEN 5001 AND 7500;
-- Dead tuple хэчнээн байгааг харах
SELECT
relname AS хүснэгт,
n_live_tup AS амьд_мөр,
n_dead_tup AS үхсэн_мөр,
ROUND(n_dead_tup * 100.0 / NULLIF(n_live_tup + n_dead_tup, 0), 1) AS үхсэн_хувь
FROM pg_stat_user_tables
WHERE relname = 'events';
UPDATE хийх бүрт PostgreSQL шинэ мөр үүсгэж хуучныг нь dead tuple болгодог. Тиймээс UPDATE ч мөн dead tuple үүсгэдэг.
VACUUM — цэвэрлэлт
-- Нэг хүснэгтийг цэвэрлэх
VACUUM events;
-- Дэлгэрэнгүй мэдээлэлтэй
VACUUM VERBOSE events;
-- Бүх хүснэгтийг цэвэрлэх
VACUUM;
Ердийн VACUUM нь dead tuple-уудыг цэвэрлэж, тухайн зайг шинэ өгөгдөлд дахин ашиглах боломжтой болгодог — гэвч дискний зайг үнэндээ буцааж өгдөггүй.
-- VACUUM FULL: дискний зайг бодитоор чөлөөлөх
-- Анхааруулга: хүснэгтийг бүрэн түгжиж, нэлээд цаг авна
VACUUM FULL events;
-- Хэмжээний өөрчлөлтийг шалгах
SELECT
relname,
pg_size_pretty(pg_total_relation_size(oid)) AS нийт_хэмжээ
FROM pg_class
WHERE relname = 'events';
VACUUM FULL нь хүснэгтийг дахин бичиж дискний зайг буцааж өгдөг — гэвч уг хугацаанд хүснэгт бүрэн түгжигддэг. Үйлдвэрлэлийн системд оройн цагаар л хийх нь зөв.
ANALYZE — статистик шинэчлэх
ANALYZE нь хүснэгтийн өгөгдлийн тархалтыг статистикт бүртгэж, PostgreSQL-н query planner зөв, хурдан гүйцэтгэлийн төлөвлөгөө гаргахад ашигладаг:
-- Статистик шинэчлэх
ANALYZE events;
-- VACUUM ба ANALYZE-г нэгэн зэрэг
VACUUM ANALYZE events;
-- Статистикийг харах
SELECT
tablename,
attname AS баганын_нэр,
n_distinct AS давтагдашгүй_утгын_тоо,
correlation AS тархалтын_зэрэг
FROM pg_stats
WHERE tablename = 'events'
ORDER BY attname;
n_distinct нь баганад хэдэн давтагдашгүй утга байгааг харуулна. Query planner энэ тоог ашиглан sequential scan эсвэл index scan аль нь хурдан болохыг тооцдог.
Autovacuum — автомат цэвэрлэлт
PostgreSQL-д autovacuum daemon нь арын дэвсгэрт байнга ажиллан хүснэгтийн dead tuple-уудыг автоматаар цэвэрлэдэг. Ихэнх тохиолдолд гараар VACUUM хийх шаардлагагүй:
-- Autovacuum хэзээ ажилласан, юу хийснийг харах
SELECT
relname AS хүснэгт,
last_vacuum AS сүүлийн_vacuum,
last_autovacuum AS сүүлийн_autovacuum,
last_analyze AS сүүлийн_analyze,
last_autoanalyze AS сүүлийн_autoanalyze,
vacuum_count,
autovacuum_count
FROM pg_stat_user_tables
ORDER BY last_autovacuum DESC NULLS LAST;
-- Хүснэгт тус бүрт autovacuum тохиргоо өөрчлөх
-- (хэт идэвхтэй шинэчлэгдэх хүснэгтэд хэрэгтэй)
ALTER TABLE events SET (
autovacuum_vacuum_scale_factor = 0.01, -- 1%-иас дээш dead tuple байвал
autovacuum_analyze_scale_factor = 0.005
);
Autovacuum ердийн горимд хангалттай. Гэхдээ маш их UPDATE/DELETE хийдэг хүснэгтэд дээрх тохиргоог тохируулах хэрэгтэй болж болно.
Дараагийн хичээлд:
EXPLAIN ANALYZE командаар PostgreSQL асуулгыг хэрхэн гүйцэтгэж байгааг уншиж, удаан асуулгыг оновчлох аргуудыг дэлгэрэнгүй сурна.