一、前言

对于含有union , group by 等的视图,我们称之为复杂视图。 这类的视图会影响优化器对于视图的提升,也就是视图无法与父查询进行合并,从而影响访问路径、连接方法、连接顺序等。本文通过例子,给大家展示PostgreSQL这类问题及针对该问题的优化方法。

二、Union 视图的优化

1、构建例子:

create table t1(id1 integer);
insert into t1 select generate_series(1,10); create table t2(id2 integer,name char(500));
insert into t2 select generate_series(1,1000000),repeat('a',400);
create index ind_t2 on t2(id2); create table t3(id3 integer,name char(500));
insert into t3 select generate_series(1,1000000),repeat('a',400);
create index ind_t3 on t3(id3); create or replace view v_t2_t3 as
select id2 as id from t2
union
select id3 as id from t3;

2、分析执行计划

执行计划如下:

testdb=# explain analyze select * from t1,v_t2_t3 where id1=id;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------
Merge Join (cost=447340.31..483340.14 rows=99999 width=8) (actual time=1313.700..1313.711 rows=10 loops=1)
Merge Cond: (t1.id1 = t2.id2)
-> Sort (cost=1.27..1.29 rows=10 width=4) (actual time=0.019..0.021 rows=10 loops=1)
Sort Key: t1.id1
Sort Method: quicksort Memory: 25kB
-> Seq Scan on t1 (cost=0.00..1.10 rows=10 width=4) (actual time=0.009..0.011 rows=10 loops=1)
-> Unique (cost=447339.04..457338.98 rows=1999988 width=4) (actual time=1313.674..1313.681 rows=10 loops=1)
-> Sort (cost=447339.04..452339.01 rows=1999988 width=4) (actual time=1313.673..1313.676 rows=19 loops=1)
Sort Key: t2.id2
Sort Method: external merge Disk: 27488kB
-> Append (cost=0.00..183333.70 rows=1999988 width=4) (actual time=0.017..923.420 rows=2000000 loops=1)
-> Seq Scan on t2 (cost=0.00..76666.94 rows=999994 width=4) (actual time=0.016..547.533 rows=1000000 loops=1)
-> Seq Scan on t3 (cost=0.00..76666.94 rows=999994 width=4) (actual time=0.014..261.595 rows=1000000 loops=1)
Planning Time: 3.124 ms
Execution Time: 1316.691 ms
(15 rows)

问题分析:视图 v_t2_t3 并没有与 t1进行合并(Unique部分),而是 t1 与 结果进行连接。这个执行计划的问题在于 t1 表的数据量很少,如果能把 t1.id1 传入到视图,视图内部访问 t2 , t3 时就可以走索引,效率上要更高。

3、修改SQL

testdb=# explain analyze select * from t1,v_t2_t3 where id1=id and id=any(array(select id1 from t1));
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
Hash Join (cost=98.95..100.08 rows=10 width=8) (actual time=0.126..0.129 rows=10 loops=1)
Hash Cond: (t1.id1 = t2.id2)
InitPlan 1 (returns $0)
-> Seq Scan on t1 t1_1 (cost=0.00..1.10 rows=10 width=4) (actual time=0.001..0.002 rows=10 loops=1)
-> Seq Scan on t1 (cost=0.00..1.10 rows=10 width=4) (actual time=0.005..0.006 rows=10 loops=1)
-> Hash (cost=97.60..97.60 rows=20 width=4) (actual time=0.115..0.116 rows=10 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> HashAggregate (cost=97.20..97.40 rows=20 width=4) (actual time=0.112..0.114 rows=10 loops=1)
Group Key: t2.id2
-> Append (cost=0.42..97.15 rows=20 width=4) (actual time=0.060..0.105 rows=20 loops=1)
-> Index Only Scan using ind_t2 on t2 (cost=0.42..48.43 rows=10 width=4) (actual time=0.060..0.072 rows=10 loops=1)
Index Cond: (id2 = ANY ($0))
Heap Fetches: 10
-> Index Only Scan using ind_t3 on t3 (cost=0.42..48.43 rows=10 width=4) (actual time=0.022..0.032 rows=10 loops=1)
Index Cond: (id3 = ANY ($0))
Heap Fetches: 10
Planning Time: 0.171 ms
Execution Time: 0.163 ms
(18 rows)

  

分析:通过增加条件 id=any(array(select id1 from t1)) , 可以看到该条件可以传入到视图内部。视图内部对于 t2 , t3 的访问是走索引的。

4、问题分析结论

对于类似 v_t2_t3 这种含有 union 的复杂视图,除非是指定明确的值,如 v_t2_t3.id=xxx , 才可以传入的视图内部。 而对于连接条件,如: id1=id,则无法将 id1 传入到视图内部,这时视图只能走全表访问。

三、KingbaseES 提升了优化器能力

KingbaseES 通过修改优化器算法,实现了在RBO 层面对于该类SQL 的改写,避免了该问题。

PostgreSQL 涉及复杂视图查询的优化案例的更多相关文章

  1. 【PostgreSQL】 前缀模糊查询级优化

    前匹配模糊 使用B-Tree来加速优化前匹配模糊查询 构造数据 新建一张商品表,插入一千万条数据. create table goods(id int, name varchar); insert i ...

  2. 记一次mysql多表查询(left jion)优化案例

    一次mysql多表查询(left jion)优化案例 在新上线的供需模块中,发现某一个查询按钮点击后,出不来结果,找到该按钮对应sql手动执行,发现需要20-30秒才能出结果,所以服务端程序判断超时, ...

  3. 数据库优化案例——————某知名零售企业ERP系统

    写在前面 记得在自己学习数据库知识的时候特别喜欢看案例,因为优化的手段是容易掌握的,但是整体的优化思想是很难学会的.这也是为什么自己特别喜欢看案例,今天也分享自己做的优化案例. 之前分享过OA系统.H ...

  4. 数据库优化案例——————某市中心医院HIS系统

    记得在自己学习数据库知识的时候特别喜欢看案例,因为优化的手段是容易掌握的,但是整体的优化思想是很难学会的.这也是为什么自己特别喜欢看案例,今天也开始分享自己做的优化案例. 最近一直很忙,博客产出也少的 ...

  5. mysql笔记03 查询性能优化

    查询性能优化 1. 为什么查询速度会慢? 1). 如果把查询看作是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间.如果要优化查询,实际上要优化其子任务,要么消除其中一些子任务,要么减 ...

  6. MySQL查询性能优化(精)

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

  7. 170727、MySQL查询性能优化

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

  8. MySQL/MariaDB数据库的查询缓存优化

    MySQL/MariaDB数据库的查询缓存优化 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL架构 Connectors(MySQL对外提供的交互接口,API): ...

  9. 《高性能MySQL》之MySQL查询性能优化

    为什么查询会慢? 响应时间过长.如果把查询看做是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间.如果要优化查询,实际上优化其子任务,要么消除其中一些子任务,要么减少子任务的执行次数, ...

随机推荐

  1. ASP.NET MVC的核心-Controller(控制器)

    "每一个请求都必须通过Controller处理,然而其中有些请求是不需要模型和视图的" MVC框架规定带Controller后缀的类称为所谓的"控制器",在xx ...

  2. dubbox、zookeeper BUG记录

    主要错误信息: dubbo:com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method... Caused by: com.alib ...

  3. centos7.6部署DRBD提示“no resources defined!

    环境准备: node1(主节点)IP: 192.168.26.30 主机名:node1node2(从节点)IP: 192.168.26.31 主机名:node2 1.关闭防火墙和selinux #se ...

  4. 013(oulipo)

    题目:http://ybt.ssoier.cn:8088/problem_show.php?pid=1455 题目描述:在母串里找子串出现的次数 题目思路:与字符串的搜索有关那就立刻找到哈希 从s[1 ...

  5. C++基本数据类型范围和区别(详细)

    一.基本类型的大小及范围的总结(以下所讲都是默认在32位操作系统下):字节:byte:位:bit.1.短整型short:所占内存大小:2byte=16bit:所能表示范围:-32768~32767:( ...

  6. S32K148_CAN驱动(裸机开发)

    hello,大家好.今天我又来啦,今天记录一下S32K148-CAN裸机驱动编写,有错误地方欢迎大家指正. CAN的发送接收在S32K148中主要有三种方式,一种是邮箱机制(mailbox),一种FI ...

  7. hive SQL 初学者题目,实战题目 字符串函数,日期拼接,开窗函数。。。。

    sql:Hive实现按照指定格式输出每七天的消费平均数输出格式:2018-06-01~2018-06-07 12.29...2018-08-10~2018-08-16 80.67 答案:-- 1.先将 ...

  8. 日志审计与分析实验三(rsyslog服务器端和客户端配置)(Linux日志收集)

    Linux日志收集 一.实验目的: 1.掌握rsyslog配置方法 2.配置rsyslog服务收集其他Linux服务器日志: C/S架构:客户端将其日志上传到服务器端,通过对服务器端日志的查询,来实现 ...

  9. ASP.NET Core 6.0 基于模型验证的数据验证

    1 前言 在程序中,需要进行数据验证的场景经常存在,且数据验证是有必要的.前端进行数据验证,主要是为了减少服务器请求压力,和提高用户体验:后端进行数据验证,主要是为了保证数据的正确性,保证系统的健壮性 ...

  10. 小白之Python基础(五)

    使用dict和set 1.dict :是direction字典的缩写 1) 通过{ }创建,使用健-值(key-value)存储:用"键值对"表示映射关系,例如 {名字:对应的成绩 ...