系统慢sql的解决方案

一、大表分区

二、创建索引

创建评估

sql 复制代码
-- 检查查询计划,看是否需要索引
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 123;

-- 检查列的基数(不同值的数量)
SELECT COUNT(DISTINCT user_id) FROM orders;
SELECT COUNT(DISTINCT status) FROM orders;  -- 低基数列可能不适合索引

创建索引

0、基本语法

sql 复制代码
-- 基本语法
CREATE [UNIQUE] INDEX [CONCURRENTLY] [索引名] ON 表名 [USING 索引类型] (列名 [选项]);

-- 最简单的形式
CREATE INDEX idx_users_email ON users(email);

1、B-tree索引(默认)

sql 复制代码
-- 单列索引
CREATE INDEX idx_orders_user_id ON orders(user_id);

-- 多列索引(复合索引)
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);

-- 唯一索引,也可多列
CREATE UNIQUE INDEX idx_users_email_unique ON users(email);

-- 带条件的部分索引
CREATE INDEX idx_active_users ON users(email) WHERE status = 'active';

2、其他索引

sql 复制代码
-- Hash索引(等值查询)
CREATE INDEX idx_users_id_hash ON users USING HASH (id);

-- GIN索引(全文搜索、数组、JSONB)
CREATE INDEX idx_products_tags ON products USING GIN (tags);
CREATE INDEX idx_docs_content ON documents USING GIN (to_tsvector('english', content));

-- GiST索引(地理空间、范围类型)
CREATE INDEX idx_locations_coords ON locations USING GIST (coords);

-- BRIN索引(超大型表,数据天然有序)
CREATE INDEX idx_logs_created_at ON logs USING BRIN (created_at);

3、高级选项

sql 复制代码
-- 普通创建索引会锁表,阻止写操作
-- 并发创建允许在创建索引时继续读写
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);

-- 为频繁更新的列预留空间
CREATE INDEX idx_products_stock ON products(stock) WITH (fillfactor = 70);

-- 将索引创建在特定表空间(如SSD盘)
CREATE INDEX idx_large_table_date ON large_table(created_at) TABLESPACE fast_ssd;

查看索引

sql 复制代码
-- 查看表上的所有索引
SELECT * FROM pg_indexes WHERE tablename = 'users';

-- 更详细的信息(包括索引大小)
SELECT 
    i.relname as index_name,
    pg_size_pretty(pg_relation_size(i.oid)) as index_size,
    idx_scan as index_scans
FROM pg_class t
JOIN pg_index ON t.oid = pg_index.indrelid
JOIN pg_class i ON i.oid = pg_index.indexrelid
WHERE t.relname = 'users';

删除索引

sql 复制代码
-- 删除索引
DROP INDEX idx_users_email;

-- 如果索引存在则删除(避免报错)
DROP INDEX IF EXISTS idx_users_email;

-- PostgreSQL 14+ 支持并发删除索引(不阻塞读写)
DROP INDEX CONCURRENTLY idx_users_email;

-- 删除依赖该索引的对象(如使用了该索引的约束)
DROP INDEX idx_users_email CASCADE;

三、预计算之创建物化视图

与普通视图不同,物化视图实际存储了结果数据,PostgreSQL会将其视为一个独立的、只读的表,因此,直接查询物化视图速度更快,另外,可以在其上创建索引来加速针对该物化视图的查询。而且,即使创建物化视图的源表上有索引,这些索引也不会自动传递给物化视图,必须为物化视图单独创建索引。当对应的,普通视图只是一个逻辑映射,它本身没有物理存储,每次查询时都要实时执行定义普通视图时的sql语句。为普通视图编写的查询,其性能取决于视图定义查询语句和底层物理表的数据量及索引。如果底层表有合适的索引,查询视图时就能用上。当然,物化视图也有缺点:1、数据通常是定时刷新,其新鲜度取决于刷新频率,一般无法获得最新鲜的数据;2、postgresql本身并不提供调度工具,需要第三发的调度器去刷新数据;

sql 复制代码
  -- 创建物化视图
  CREATE MATERIALIZED VIEW IF NOT EXISTS v_scene_site_cell
	AS
	-- 23万 虚拟子表,提取"场景类型1"、"场景名称"、"基站号_扇区号"
	select distinct ts.f_first_type, f_scene_name, f_site_cell_id 
	-- 3.5万(场景信息【静态表】)
	from t_ten_scene ts
	-- 37.5万(场景~扇区映射【静态表】)
	left join t_ten_scene_sector tss on ts.f_id = tss.f_ten_scene_id
	left join (
	    -- 31.6万(4G扇区信息【静态表】)
		select f_site_id || '_' || f_cell_id f_site_cell_id, f_id from t_lte_sector where f_delete_flag is null
		union
		-- 37.1万(5G扇区信息【静态表】)
		select f_site_id || '_' || f_cell_id f_site_cell_id, f_id from t_five_sector where f_delete_flag is null
	) ss on tss.f_sector_id = ss.f_id
	where f_site_cell_id is not null;
	
	SELECT * from v_scene_site_cell;
sql 复制代码
	-- 先创建唯一索引
	CREATE UNIQUE INDEX idx_uniq_scene_site_cell ON v_scene_site_cell(f_first_type, f_scene_name, f_site_cell_id);
	-- 再进行并发刷新
	REFRESH MATERIALIZED VIEW CONCURRENTLY v_scene_site_cell;
sql 复制代码
	-- 创建索引用于查询加速
	CREATE INDEX idx_scene_site_cell_site_cell_id ON v_scene_site_cell(f_site_cell_id)

四、使用缓存

包括本地缓存和远程缓存(如redis)。使用缓存的有点是:查询速度极快。缺点是:1、当第一次查询或缓存过期后需要重新查库,速度较慢;2、缓存通常是定时更新,无法查到最新鲜的数据;3、本地缓存空间资源比较有限,不适合大数据量;

相关推荐
知识分享小能手9 小时前
PostgreSQL 入门学习教程,从入门到精通,PostgreSQL 16 服务器配置与数据库监控终极指南 —语法、案例与实战(18)
数据库·学习·postgresql
宇灬宇11 小时前
Oracle 到 PostgreSQL迁移(ora2pg)
数据库·postgresql·oracle
高铭杰11 小时前
Postgresql源码(155)Redo系列CLOG Redo (RM_CLOG_ID = 3)
数据库·postgresql·redo·clog
执笔画情ora13 小时前
pg数据库管理-PostgreSQL 的 COPY TO 和 COPY FROM 命令
数据库·postgresql
爱吃牛肉的大老虎13 小时前
PostgreSQL基础之安装
数据库·postgresql
MrMua14 小时前
mysql与postgresql对比
数据库·mysql·postgresql
程序员夏末15 小时前
【JchatMind智能体 | 第二天】为何选 PostgreSQL + pgvector 而非 MySQL?
数据库·mysql·postgresql·ai编程·ai agent
劈星斩月15 小时前
PostgreSQL-02-数据类型(数字类型)
postgresql·数据类型·浮点类型·数字类型
_半夏曲1 天前
PostgreSQL 13、14、15 区别
数据库·postgresql