PostgreSQL 改元信息 实现 invalid index

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS SQL Server,基础系列 2核4GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介:

标签

PostgreSQL , 索引 , invalid


背景

某些时候,可能想避免一些索引的影响,特意让优化器不选择使用某些索引。

通常的做法可能有:

1、HINT

《关键时刻HINT出彩 - PG优化器的参数优化、执行计划固化CASE》

《PostgreSQL SQL HINT的使用(pg_hint_plan)》

2、设置开关,(注意它不能只影响某一个索引,会影响一片)

#enable_bitmapscan = on  
#enable_hashagg = on  
#enable_hashjoin = on  
#enable_indexscan = on  
#enable_indexonlyscan = on  
#enable_material = on  
#enable_mergejoin = on  
#enable_nestloop = on  
#enable_parallel_append = on  
#enable_seqscan = on  
#enable_sort = on  
#enable_tidscan = on  
#enable_partitionwise_join = off  
#enable_partitionwise_aggregate = off  
#enable_parallel_hash = on  
enable_partition_pruning = on  

还有一种做法是,把索引设置为invalid,此时优化器不会使用这个索引,同时数据有更新,写入时依旧会更新这个索引。

实际上在CREATE INDEX CONCURRENTLY时完成第一阶段后,索引实际上就是INVALID的,但是数据的DML依旧会对INVALID的索引产生修改,所以可以保证索引本身的完整性。只是优化器不用它而已。

修改元数据来实现invalid index

1、创建测试表

postgres=# create table ii (id int primary key, info text);  
CREATE TABLE  

2、创建测试索引

postgres=# create index i_ii on ii(info);  
CREATE INDEX  

3、写入测试数据几条

postgres=# insert into ii values (1,'test');  
INSERT 0 1  

4、使用索引扫描,查询到目标数据

postgres=# set enable_seqscan=off;  
SET  
postgres=# set enable_bitmapscan=off;  
SET  
postgres=# select * from ii where info='test';  
 id | info   
----+------  
  1 | test  
(1 row)  
  
postgres=# explain select * from ii where info='test';  
                            QUERY PLAN                              
------------------------------------------------------------------  
 Index Scan using i_ii on ii  (cost=0.16..13.81 rows=26 width=36)  
   Index Cond: (info = 'test'::text)  
(2 rows)  

5、更新元数据,将这个索引设置为INVALID

postgres=# update pg_index set indisvalid=false where indexrelid='i_ii'::regclass;  
UPDATE 1  

6、重新执行查询,优化器不会再选择索引扫描,而是使用了全表扫描

postgres=# explain select * from ii where info='test';  
                               QUERY PLAN                                 
------------------------------------------------------------------------  
 Seq Scan on ii  (cost=10000000000.00..10000000073.88 rows=26 width=36)  
   Filter: (info = 'test'::text)  
 JIT:  
   Functions: 2  
   Inlining: true  
   Optimization: true  
(6 rows)  
  
postgres=# select * from ii where info='test';  
 id | info   
----+------  
  1 | test  
(1 row)  

7、在将索引设置为invalid后,再次写入若干数据

postgres=# insert into ii values (2,'test1');  
INSERT 0 1  
postgres=# insert into ii values (3,'test3');  
INSERT 0 1  
postgres=# explain select * from ii where info='test';  
                               QUERY PLAN                                 
------------------------------------------------------------------------  
 Seq Scan on ii  (cost=10000000000.00..10000000073.88 rows=26 width=36)  
   Filter: (info = 'test'::text)  
 JIT:  
   Functions: 2  
   Inlining: true  
   Optimization: true  
(6 rows)  
  
postgres=# select * from ii where info='test1';  
 id | info    
----+-------  
  2 | test1  
(1 row)  
  
postgres=# insert into ii select generate_series(4,100000),md5(random()::Text);  
INSERT 0 99997  

8、更新元数据,将索引恢复为VALID

postgres=# update pg_index set indisvalid=true where indexrelid='i_ii'::regclass;  
UPDATE 1  

9、查看执行计划,使用了索引扫描

postgres=# explain select * from ii where info='test';  
                           QUERY PLAN                             
----------------------------------------------------------------  
 Index Scan using i_ii on ii  (cost=0.29..2.71 rows=1 width=37)  
   Index Cond: (info = 'test'::text)  
(2 rows)  

10、使用索引扫描,可以找到在INVALID索引后,写入的数据。

postgres=# select * from ii where info='test1';  
 id | info    
----+-------  
  2 | test1  
(1 row)  
  
postgres=# select * from ii where info='test2';  
 id | info   
----+------  
(0 rows)  
  
postgres=# select * from ii where info='test3';  
 id | info    
----+-------  
  3 | test3  
(1 row)  
  
postgres=# explain select * from ii where info='test3';  
                           QUERY PLAN                             
----------------------------------------------------------------  
 Index Scan using i_ii on ii  (cost=0.29..2.71 rows=1 width=37)  
   Index Cond: (info = 'test3'::text)  
(2 rows)  
  
postgres=# select * from ii where id=99999;  
  id   |               info                 
-------+----------------------------------  
 99999 | 54382fc94aba553b8972ce2657a7bdfb  
(1 row)  
  
postgres=# explain select * from ii where info='54382fc94aba553b8972ce2657a7bdfb';  
                           QUERY PLAN                              
-----------------------------------------------------------------  
 Index Scan using i_ii on ii  (cost=0.29..2.71 rows=1 width=37)  
   Index Cond: (info = '54382fc94aba553b8972ce2657a7bdfb'::text)  
(2 rows)  
  
postgres=# select * from ii where info='54382fc94aba553b8972ce2657a7bdfb';  
  id   |               info                 
-------+----------------------------------  
 99999 | 54382fc94aba553b8972ce2657a7bdfb  
(1 row)  

相信未来PG内核会扩展ALTER INDEX或ALTER TABLE的语法,在语法层面支持INVALID INDEX。

参考

《PostgreSQL CREATE INDEX CONCURRENTLY 的原理以及哪些操作可能堵塞索引的创建》

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
存储 关系型数据库 分布式数据库
PolarDB产品使用问题之如何查看PolarDB for PostgreSQL的备份信息
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
SQL 关系型数据库 PostgreSQL
PostgreSQL【SQL 01】根据条件更新字段值或追加信息STRPOS(string, substring)函数使用及LIKE函数对比
PostgreSQL【SQL 01】根据条件更新字段值或追加信息STRPOS(string, substring)函数使用及LIKE函数对比
415 0
|
SQL 关系型数据库 Java
PostgreSQL统计信息的几个重要视图
PostgreSQL统计信息的几个重要视图
454 1
|
存储 运维 Cloud Native
【实操系列】基于AnalyticDB PostgreSQL数据共享实现企业级跨多业务的敏捷分析
云数据仓库AnalyticDB PostgreSQL 版发布了最新自研的云原生架构实例,实现了跨实例间的数据共享能力。允许进行跨实例间的实时数据共享且无需进行数据迁移,可支持构建安全、高效、灵活的数据分析场景。本文介绍了依托数据共享实现云数仓跨多业务实例的敏捷数据分析方案;
【实操系列】基于AnalyticDB PostgreSQL数据共享实现企业级跨多业务的敏捷分析
|
SQL 缓存 监控
PostgreSQL 监控1统计进程和统计信息的解读|学习笔记(二)
快速学习PostgreSQL 监控1统计进程和统计信息的解读
506 0
PostgreSQL 监控1统计进程和统计信息的解读|学习笔记(二)
|
SQL 监控 IDE
PostgreSQL监控1统计进程和统计信息的解读|学习笔记(一)
快速学习PostgreSQL监控1统计进程和统计信息的解读
704 0
PostgreSQL监控1统计进程和统计信息的解读|学习笔记(一)
|
SQL 存储 Oracle
PostgreSQL 事务隔离级别的实现和多版本并发控制|学习笔记
快速学习 PostgreSQL 事务隔离级别的实现和多版本并发控制
PostgreSQL 事务隔离级别的实现和多版本并发控制|学习笔记
|
关系型数据库 测试技术 PostgreSQL
postgresql实现影响分析
通过postgresql模仿分析假如城市发布通知,位于街道的人员是否受到了影响
179 0
postgresql实现影响分析
|
弹性计算 资源调度 运维
【实操系列】 AnalyticDB PostgreSQL发布实例计划管理功能,实现资源分时弹性&分时启停
本文将对AnalyticDB PostgreSQL产品的计划任务管理功能以及其背后的实现机制和最佳实践做详细介绍。
【实操系列】 AnalyticDB PostgreSQL发布实例计划管理功能,实现资源分时弹性&分时启停
|
存储 SQL 网络协议
PolarDB for PostgreSQL 采用iprange和SPGiST index 实现超光速 - 全球化业务根据来源IP智能DNS路由就近分配本地机房访问, 提升用户体验
[《如何获得IP地址对应的地理信息库, 实现智能DNS解析? 就近路由提升全球化部署业务的访问性能》](../202211/20221124_09.md) 上一篇信息提到了如何获取IP地址段的地理信息库, 本篇信息将使用PolarDB for PostgreSQL来加速根据来源IP快速找到对应的IP地址段, 将用到PolarDB for PostgreSQL的SPGiST索引和inet数据类型. 相比于把IP地址段存储为2个int8字段作between and的匹配, SPGiST索引和inet数据类型至少可以提升20倍性能.
352 0

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版
  • 推荐镜像

    更多