PostgreSQL 与 Oracle 访问分区表执行计划差异
熟悉Oracle 的DBA都知道,Oracle 访问分区表时,对于没有提供分区条件的,也就是在无法使用分区剪枝情况下,优化器会根据全局的统计信息制定执行计划,该执行计划针对所有分区适用。在分析利弊之前,我们先来看个例子:
一、Oracle
构建数据:
create table part_tab01(part_key char(1),state char(1),desc_content varchar(4000))
partition by range(part_key)
(
partition part_0 values less than(1),
partition part_1 values less than(2)
); insert into part_tab01 select '0','0',rpad('a',1000,'a') from dba_objects where rownum<10001;
insert into part_tab01 select '1','1',rpad('a',1000,'a') from dba_objects where rownum<10001;
insert into part_tab01 select * from part_tab01;
insert into part_tab01 select * from part_tab01;
insert into part_tab01 select * from part_tab01;
insert into part_tab01 select * from part_tab01;
insert into part_tab01 select * from part_tab01;
insert into part_tab01 select * from part_tab01;
insert into part_tab01 select '1','0',rpad('a',1000,'a') from dba_objects where rownum<11;
insert into part_tab01 select '0','1',rpad('a',1000,'a') from dba_objects where rownum<11; create index idx_part_tab01_state on part_tab01(state) local;
从数据的分布可以得出结论,最优的访问方法:对于不同的分区,访问不同的state 值,应采用不同的表访问方法。
执行计划:
SQL> select * from part_tab01 where state='1'; 640010 rows selected. Execution Plan
----------------------------------------------------------
Plan hash value: 4116343635 --------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 640K| 613M| 49576 (1)| 00:00:02 | | |
| 1 | PARTITION RANGE ALL| | 640K| 613M| 49576 (1)| 00:00:02 | 1 | 2 |
|* 2 | TABLE ACCESS FULL | PART_TAB01 | 640K| 613M| 49576 (1)| 00:00:02 | 1 | 2 |
-------------------------------------------------------------------------------------------------- SQL> select * from part_tab01 where state='1' and part_key='0'; 10 rows selected. Execution Plan
----------------------------------------------------------
Plan hash value: 1952449058 -----------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 10050 | 5 (0)| 00:00:01 | | |
| 1 | PARTITION RANGE SINGLE | | 10 | 10050 | 5 (0)| 00:00:01 | 1 | 1 |
|* 2 | TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| PART_TAB01 | 10 | 10050 | 5 (0)| 00:00:01 | 1 | 1 |
|* 3 | INDEX RANGE SCAN | IDX_PART_TAB01_STATE | 10 | | 3 (0)| 00:00:01 | 1 | 1 |
----------------------------------------------------------------------------------------------------------------------------------- SQL> select * from part_tab01 where state='1' and part_key='1'; 640000 rows selected. Execution Plan
----------------------------------------------------------
Plan hash value: 4278184147 -----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 640K| 613M| 24793 (1)| 00:00:01 | | |
| 1 | PARTITION RANGE SINGLE| | 640K| 613M| 24793 (1)| 00:00:01 | 2 | 2 |
|* 2 | TABLE ACCESS FULL | PART_TAB01 | 640K| 613M| 24793 (1)| 00:00:01 | 2 | 2 |
-----------------------------------------------------------------------------------------------------
可以看到,在没有分区条件的情况下,Oracle 是针对全表采用统一的执行。实际针对该SQL,最好的访问方法应该是:part_0 全表,part_1 索引
二、PostgreSQL 执行计划
构建数据:
create table part_tab01(part_key char(1),state char(1),desc_content text)
partition by range(part_key)
(
partition part_0 values less than(1),
partition part_1 values less than(2)
); insert into part_tab01 select '0','0',repeat('a',1000) from generate_series(1,1000000);
insert into part_tab01 select '0','1',repeat('b',1000) from generate_series(1,10);
insert into part_tab01 select '1','1',repeat('a',1000) from generate_series(1,1000000);
insert into part_tab01 select '1','0',repeat('b',1000) from generate_series(1,10); create index idx_part_tab01_state on part_tab01(state);
执行计划:针对不同分区,有不同的执行计划。
test=# explain analyze select * from part_tab01 where state='1';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------
Append (cost=0.42..160363.43 rows=1000000 width=1008) (actual time=0.022..484.005 rows=1000010 loops=1)
-> Index Scan using part_tab01_part_0_state_idx on part_tab01_part_0 (cost=0.42..4.44 rows=1 width=1008) (actual time=0.022..0.024 rows=10 loops=1)
Index Cond: (state = '1'::bpchar)
-> Seq Scan on part_tab01_part_1 (cost=0.00..155358.99 rows=999999 width=1008) (actual time=0.011..424.713 rows=1000000 loops=1)
Filter: (state = '1'::bpchar)
Rows Removed by Filter: 10
Planning Time: 0.293 ms
Execution Time: 515.549 ms
(8 rows) test=# explain analyze select * from part_tab01 where state='0';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------
Append (cost=0.00..160363.68 rows=1000014 width=1008) (actual time=0.022..517.127 rows=1000010 loops=1)
-> Seq Scan on part_tab01_part_0 (cost=0.00..155359.16 rows=1000013 width=1008) (actual time=0.022..451.523 rows=1000000 loops=1)
Filter: (state = '0'::bpchar)
Rows Removed by Filter: 10
-> Index Scan using part_tab01_part_1_state_idx on part_tab01_part_1 (cost=0.42..4.44 rows=1 width=1008) (actual time=0.032..0.035 rows=10 loops=1)
Index Cond: (state = '0'::bpchar)
Planning Time: 0.090 ms
Execution Time: 547.486 ms
(8 rows)
三、结论
从本例可以看出,在不同分区数据分布不同的场景下,PostgreSQL针对不同分区有独立的执行计划是更优方法。现实中典型的场景,如:按时间分区的工单表,历史分区可能大部分工单是结束状态,而当前分区工单可能大部分是非结束状态。
PostgreSQL 与 Oracle 访问分区表执行计划差异的更多相关文章
- Oracle查看SQL执行计划的方式
Oracle查看SQL执行计划的方式 获取Oracle sql执行计划并查看执行计划,是掌握和判断数据库性能的基本技巧.下面案例介绍了多种查看sql执行计划的方式: 基本有以下几种方式: ...
- Oracle中的执行计划
使用autotrace sqlplus系统参数:SQL> set autotrace trace onSQL> select * from dual;DUM---XExecution Pl ...
- ORACLE数据库中执行计划出现INTERNAL_FUNCTION一定是隐式转换吗?
ORACLE数据库中,我们会使用一些SQL语句找出存在隐式转换的问题SQL,其中网上流传的一个SQL语句如下,查询V$SQL_PLAN的字段FILTER_PREDICATES中是否存在INTERNAL ...
- Oracle中获取执行计划的几种方法分析
以下是对Oracle中获取执行计划的几种方法进行了详细的分析介绍,需要的朋友可以参考下 1. 预估执行计划 - Explain PlanExplain plan以SQL语句作为输入,得到这条S ...
- Oracle性能优化之Oracle里的执行计划
一.执行计划 执行计划是目标SQL在oracle数据库中具体的执行步骤,oracle用来执行目标SQL语句的具体执行步骤的组合被称为执行计划. 二.如何查看oracle数据库的执行计划 oracle数 ...
- 基于Oracle的SQL优化(崔华著)-整理笔记-第2章“Oracle里的执行计划”
详细介绍了Oracle数据里与执行计划有关的各个方面的内容,包括执行计划的含义,加何查看执行计划,如何得到目标SQL真实的执行计划,如何查看执行计划的执行顺序,Oracle数据库里各种常见的执行计划的 ...
- Oracle - SPM固定执行计划
1. 通过dbms_xplan.display_cursor查看指定sql都有哪些执行计划 SQL> select * from table(dbms_xplan.display_cursor( ...
- Oracle数据库查看执行计划
基于ORACLE的应用系统很多性能问题,是由应用系统SQL性能低劣引起的,所以,SQL的性能优化很重要,分析与优化SQL的性能我们一般通过查看该SQL的执行计划,本文就如何看懂执行计划,以及如何通过分 ...
- 转://看懂Oracle中的执行计划
一.什么是Oracle执行计划? 执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述 二.怎样查看Oracle执行计划? 2.1 explain plan for命令查看执行计划 在sq ...
随机推荐
- BUUCTF-一叶障目
一叶障目 010editor打开没发现有什么异常,看分辨率尺寸觉得不对劲,修改了一下发现了flag 图片第二组前面四个是宽后面是高,修改第七位为05即可发现flag flag{66666}
- 第一章:Python的数据结构、函数和文件
list list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可以用一个list表示: >>> classmates = ['Michael', ...
- ASP.NET MVC之models_list传值view
单个用户在查看个人信息时,一个model就能解决 但是如果是管理员,就需要查看多个用户,此时我们从数据库读一页的用户数据(大致十条) 此时返回的就可能是一个泛型列表 所以除了基本的用户model外(比 ...
- Kali MSF漏洞利用
一.前言 漏洞利用是获得系统控制权限的重要途经.用户从目标系统中找到容易攻击的漏洞,然后利用该漏洞获取权限,从而实现对目标系统的控制. 二.Metasploitable Metasploitable是 ...
- UiPath存在图像Image Exists的介绍和使用
一.Image Exists的介绍 检查是否在指定的UI元素中找到图像,输出的是一个布尔值 二.Image Exists在UiPath中的使用 1. 打开设计器,在设计库中新建一个Sequence,为 ...
- Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程
上文,我们看了IOC设计要点和设计结构:紧接着这篇,我们可以看下源码的实现了:Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的. ...
- Java数组的基本操作
public class Array1 { public static void main(String[] args) { int [] num={1,2,3,4,5}; System.out.pr ...
- 交警也觉得妙——Python 识别车牌
车牌识别在高速公路中有着广泛的应用,比如我们常见的电子收费(ETC)系统和交通违章车辆的检测,除此之外像小区或地下 车库门禁也会用到,基本上凡是需要对车辆进行身份检测的地方都会用到. 一些背景: 车牌 ...
- 8.4 苹果macOS电脑如何安装Java开发环境(JDK)
和Windows电脑安装差不多. 下载 来到JDK官方下载界面,点击Java SE 8(简称JDK 8)后面的JDK下载,来到该界面,先同意协议,然后下载对应平台的JDK,我们这里下载Mac OS X ...
- java反序列化漏洞专项
背景条件:java的框架,java的应用程序,使用序列化,反序列化操作非常多.在漏洞挖掘中,代码审计中,安全研究中,反序列化漏洞是个重点项,不可忽视.尤其是java应用程序的rce,10个里面有7个是 ...