Postgresql查询效率计算初探

 更新时间:2020年7月11日 17:22  点击:1827

摘要

关系数据库很重要的一个方面是查询速度。查询速度的好坏,直接影响一个系统的好坏。

查询速度一般需要通过查询规划来窥视执行的过程。

查询路径会选择查询代价最低的路径执行。而这个代价是怎么算出来的呢。

主要关注的参数和表

参数:来自postgresql.conf文件,可以通过show 来查看

seq_page_cost = 1.0     # measured on an arbitrary scale
random_page_cost = 4.0     # same scale as above
cpu_tuple_cost = 0.01     # same scale as above
cpu_index_tuple_cost = 0.005   # same scale as above
cpu_operator_cost = 0.0025    # same scale as above
parallel_tuple_cost = 0.1    # same scale as above
parallel_setup_cost = 1000.0   # same scale as above 

表(视图): pg_class(主要关注relpages, reltuples), pg_stats

分析简单的查询的成本计算过程

建立模拟数据,插入100000条数据进入一个表

create table test(id int, info text);
insert into test(id, info) select i, md5(i::text) from generate_series(1, 100000) t(i); 

没有索引的情况

分析全表查询的成本计算过程

postgres=# analyze test;  #防止没有分析
postgres=# explain select * from test;
       QUERY PLAN       
-------------------------------------------------------------
 Seq Scan on test (cost=0.00..1834.00 rows=100000 width=37) 

1.查询pg_class表,查看test表的page数量和行数

postgres=# select t.relpages, t.reltuples from pg_class t where t.relname = 'test';
 relpages | reltuples 
----------+-----------
  834 | 100000 

成本为1834.00是怎么算出来的?

2.这个过程,实际上是顺序扫描了834个page,节点发射了100000行

3.查看配置参数

seq_page_cost = 1.0 
cpu_tuple_cost = 0.01 

4.得出的结果就是

postgres=# select 834 * 1.0 + 100000 * 0.01;
 ?column? 
----------
 1834.00 

5.得出来的查询成本就是 1834.00。和上面的查询计划算出来的一致。

全表加入条件的成本计算过程

postgres=# explain select * from test where id = 100;
      QUERY PLAN      
--------------------------------------------------------
 Seq Scan on test (cost=0.00..2084.00 rows=1 width=37)
 Filter: (id = 100) 

成本 2084.00是怎么算出来的?

1.查询pg_class表, pages,tuples和上面的例子一样

2.这个过程就是顺序test表,发射100000行,然后通过云存过滤了100000行

3.查看过滤运算一行的代价

cpu_operator_cost = 0.0025 

4.得出的结果是

postgres=# select 834 * 1.0 + 100000 * 0.01 + 100000 * 0.0025;
 ?column? 
-----------
 2084.0000

加入索引的情况

```
create index on test(id);
```

对比下面的四种情况

Index Only Scan

postgres=# explain select id from test where id = 100;
                 QUERY PLAN                 
-----------------------------------------------------------------------------
 Index Only Scan using test_id_idx on test (cost=0.29..8.31 rows=1 width=4)
  Index Cond: (id = 100) 

Index Scan

postgres=# explain select * from test where id = 100;
                QUERY PLAN                
-------------------------------------------------------------------------
 Index Scan using test_id_idx on test (cost=0.29..8.31 rows=1 width=37)
  Index Cond: (id = 100) 

Index Scan

postgres=# explain select * from test where id < 100;
                 QUERY PLAN                 
----------------------------------------------------------------------------
 Index Scan using test_id_idx on test (cost=0.29..10.11 rows=104 width=37)
  Index Cond: (id < 100) 

把数据乱序插入

truncate table test;
insert into test(id, info) select i, md5(i::text) from generate_series(1, 1000000) t(i) order by random();

postgres=# explain select * from test where id < 100;
                 QUERY PLAN                 
----------------------------------------------------------------------------
 Bitmap Heap Scan on test (cost=5.22..380.64 rows=102 width=37)
  Recheck Cond: (id < 100)
  -> Bitmap Index Scan on test_id_idx (cost=0.00..5.19 rows=102 width=0)
     Index Cond: (id < 100)

结论

  • 有索引的时候,成本会大大减少。
  • 执行计划跟数据的分布有很大的关系。
  • 有索引的分析相对复杂一点,可以先参考官方源码实现。后面再补充上来

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对猪先飞的支持。

[!--infotagslink--]

相关文章

  • Mybatis Plus select 实现只查询部分字段

    这篇文章主要介绍了Mybatis Plus select 实现只查询部分字段的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-01
  • PostgreSQL判断字符串是否包含目标字符串的多种方法

    这篇文章主要介绍了PostgreSQL判断字符串是否包含目标字符串的多种方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-23
  • PostgreSQL TIMESTAMP类型 时间戳操作

    这篇文章主要介绍了PostgreSQL TIMESTAMP类型 时间戳操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-26
  • postgresql 实现多表关联删除

    这篇文章主要介绍了postgresql 实现多表关联删除操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-02
  • Postgresql 如何选择正确的关闭模式

    这篇文章主要介绍了Postgresl 如何选择正确的关闭模式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-18
  • MyBatisPlus-QueryWrapper多条件查询及修改方式

    这篇文章主要介绍了MyBatisPlus-QueryWrapper多条件查询及修改方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2022-06-27
  • postgresql数据添加两个字段联合唯一的操作

    这篇文章主要介绍了postgresql数据添加两个字段联合唯一的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-04
  • Oracle使用like查询时对下划线的处理方法

    这篇文章主要介绍了Oracle使用like查询时对下划线的处理方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-16
  • 解决mybatis-plus 查询耗时慢的问题

    这篇文章主要介绍了解决mybatis-plus 查询耗时慢的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-04
  • Mysql效率优化定位较低sql的两种方式

    关于mysql效率优化一般通过以下两种方式定位执行效率较低的sql语句。通过慢查询日志定位那些执行效率较低的 SQL 语句,用 --log-slow-queries[=file_name] 选项启动时, mysqld 会 写一个包含所有执行时间超过 long_quer...2015-11-08
  • PostgreSQL 字符串处理与日期处理操作

    这篇文章主要介绍了PostgreSQL 字符串处理与日期处理操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-01
  • postgresql重置序列起始值的操作

    这篇文章主要介绍了postgresql重置序列起始值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-04
  • postgresql 中的时间处理小技巧(推荐)

    这篇文章主要介绍了postgresql 中的时间处理小技巧(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-29
  • 基于postgresql数据库锁表问题的解决

    这篇文章主要介绍了基于postgresql数据库锁表问题的解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-30
  • MySQL中在查询结果集中得到记录行号的方法

    如果需要在查询语句返回的列中包含一列表示该条记录在整个结果集中的行号, ISO SQL:2003 标准提出的方法是提供 ROW_NUMBER() / RANK() 函数。 Oracle 中可以使用标准方法(8i版本以上),也可以使用非标准的 ROWNUM ; MS SQL...2015-03-15
  • Node实现搜索框进行模糊查询

    这篇文章主要为大家详细介绍了Node实现搜索框进行模糊查询,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-06-28
  • PostgreSQL之分区表(partitioning)

    通过合理的设计,可以将选择一定的规则,将大表切分多个不重不漏的子表,这就是传说中的partitioning。比如,我们可以按时间切分,每天一张子表,比如我们可以按照某其他字段分割,总之了就是化整为零,提高查询的效能...2020-07-11
  • Element-ui 自带的两种远程搜索(模糊查询)用法讲解

    这篇文章主要介绍了Element-ui 自带的两种远程搜索(模糊查询)用法讲解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-29
  • Mybatis用注解写in查询的实现

    这篇文章主要介绍了Mybatis用注解写in查询的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-13
  • PostgreSQL 中的单引号与双引号用法说明

    这篇文章主要介绍了PostgreSQL 中的单引号与双引号用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-01