当前位置: 首页 > news >正文

postgresql immutable_PostgreSQL 之函数索引

640?wx_fmt=png

PostgreSQL支持函数索引,但函数必须是immutable的,变量不变时,索引本身不会变化的,所以函数当输入参数不变时,结果必须是永恒不变的。

做个实验,一次其中考试的成绩,有一张表存储学生信息,另一张表存储考试成绩,我们通过平均成绩搜索符合成绩的学生,可以使用索引吗?

使用函数索引,可以的。但是前提是,输入学号,得到平均成绩不能变化(当然成绩是不会变化的),不然数据变化,但索引不会刷新,则搜索的数据与实际不符。

例子: 

create extension btree_gist;

学生信息表

create table t_user (id int8 primary key, name text);

成绩表

create table t_score (id int8, subject text, score int4);

计算平均成绩的函数

create or replace function get_avg_score(int8) returns float8 as $$
select avg(score)::float8 from t_score where id=$1 group by id;
$$ language sql strict immutable;

插入学生信息数据

    insert into t_user values (1, 'Tim');
insert into t_user values (2, 'mike');

插入成绩

insert into t_score values ( 1, 'computor', 88);
insert into t_score values ( 1, 'math', 88);
insert into t_score values ( 1, 'english', 88);
insert into t_score values ( 2, 'computor', 56);
insert into t_score values ( 2, 'math', 45);
insert into t_score values ( 2, 'english', 65);

没有索引

test_idx=# explain  select name , get_avg_score(id) from t_user;
QUERY PLAN
------------------------------------------------------------
Seq Scan on t_user (cost=0.00..322.00 rows=1200 width=40)
(1 row)

函数索引

create index idx_t_user_score_1 on t_user using gist (id,  get_avg_score(id));

强制索引扫描

set enable_bitmapscan=off;
set enable_seqscan=off;

test_idx=# explain select name , get_avg_score(id) from t_user where get_avg_score(id) < 55;
QUERY PLAN
----------------------------------------------------------------------------------
Index Scan using idx_t_user_score_1 on t_user (cost=0.13..8.39 rows=1 width=40)
Index Cond: (get_avg_score(id) < '55'::double precision)
(2 rows)

test_idx=# select name , get_avg_score(id) from t_user where get_avg_score(id) < 65;
name | get_avg_score
------+------------------
mike | 55.3333333333333
(1 row)

如果分数登记有误,修正之后

test_idx=# update t_score set score = score + 20 where id =2;
UPDATE 3
test_idx=# select * from t_score;
id | subject | score
----+----------+-------
1 | computor | 88
1 | math | 88
1 | english | 88
2 | computor | 76
2 | math | 65
2 | english | 85
(6 rows)

下面的结果显然是错误的

test_idx=# select ctid, name , get_avg_score(id) from t_user where get_avg_score(id)  < 65;
ctid | name | get_avg_score
-------+------+------------------
(0,2) | mike | 75.3333333333333
(1 row)

重建索引后,正确返回数据

test_idx=# drop index idx_t_user_score_1;
DROP INDEX
test_idx=# create index idx_t_user_score_1 on t_user using gist (id, get_avg_score(id));
CREATE INDEX
test_idx=# select ctid, name , get_avg_score(id) from t_user where get_avg_score(id) < 65;
ctid | name | get_avg_score
------+------+---------------
(0 rows)

总结,postgresql支持函数索引,但一定要注意函数必须是immutable,当输入不变时结果必须一致。

相关文章:

  • recyclerview放不同的布局_RecyclerView 性能优化
  • mq3.8.9版本有什么不同_【SEACMS 8.9版本】从变量覆盖到变量覆盖的SQL注入漏洞
  • matlab中k-means算法_OpenCV图像处理-KMeans 图像处理
  • python中的转义字符是什么意思_python 转义字符、运算符、列表。。。。
  • python发微信公众号消息_个人微信公众号搭建Python实现 -接收和发送消息-基本说明与实现(14.2.1)...
  • python爬虫代写价格_python爬取京东价格
  • lua get reused time_利用redis-lua+python实现接口限流
  • server2008网卡驱动包_网卡工作原理详解
  • svpwm的原理及法则推导和控制算法详解_电机控制要点解疑:SPWM,SVPWM和矢量控制...
  • python删除文件指定字符串,从Python中的字符串中删除特定字符
  • python基础读后感_《python基础教程 》第一章 读书笔记
  • 二叉树的字符图形显示程序_(CSPJ)入门级C++语言试题A卷答案解析阅读程序
  • 服务器显示地址正在使用_用Windows Storage Server 2008做iSCSI存储服务器
  • 权限设计表结构超详细_超详细!!五金模具组件及工程结构设计
  • flex 下对齐_开启 flex 与 grid 布局方式之旅
  • ECMAScript6(0):ES6简明参考手册
  • JavaScript的使用你知道几种?(上)
  • Mybatis初体验
  • nginx 负载服务器优化
  • vue-router的history模式发布配置
  • 好的网址,关于.net 4.0 ,vs 2010
  • 基于webpack 的 vue 多页架构
  • 简单实现一个textarea自适应高度
  • 项目管理碎碎念系列之一:干系人管理
  • 小而合理的前端理论:rscss和rsjs
  • 一份游戏开发学习路线
  • Nginx实现动静分离
  • scrapy中间件源码分析及常用中间件大全
  • 说说我为什么看好Spring Cloud Alibaba
  • 我们雇佣了一只大猴子...
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • # 安徽锐锋科技IDMS系统简介
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • (day 12)JavaScript学习笔记(数组3)
  • (js)循环条件满足时终止循环
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (七)Knockout 创建自定义绑定
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (译)计算距离、方位和更多经纬度之间的点
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • ******IT公司面试题汇总+优秀技术博客汇总
  • ***利用Ms05002溢出找“肉鸡
  • **PHP二维数组遍历时同时赋值
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .net对接阿里云CSB服务
  • .net访问oracle数据库性能问题
  • .net与java建立WebService再互相调用
  • .net专家(张羿专栏)