Postgresql查询效率计算初探

摘要

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

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

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

主要关注的参数和表

参数:来自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)

结论

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

总结

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

(0)

相关推荐

  • PostgreSQL中使用dblink实现跨库查询的方法

    最近一个sql语句涉及到跨库的表之间的联合查询,故研究学习下. 一开始研究知道了sql语句的写法,但是执行通过不了,需要先安装dblink扩展.这些博文里都没说清楚,感谢网友指点,在windows下只需要在相应的数据库下执行sql语句"create extension dblink"就ok了.而以上的博文基本上说的都是linux下的操作方法,也因此我走了弯路. 2.下载了PostgreSQL的源代码,却不知道语句在哪执行,貌似是在linux下的shell里执行的,我却在psql和cmd

  • 在PostgreSQL中实现递归查询的教程

     介绍 在Nilenso,哥在搞一个 (开源的哦!)用来设计和发起调查的应用. 下面这个是一个调查的例子: 在内部,它是这样表示滴: 一个调查包括了许多问题(question).一系列问题可以归到(可选)一个分类(category)中.我们实际的数据结构会复杂一点(特别是子问题sub-question部分),但先当它就只有question跟category吧. 我们是这样保存question跟category的. 每个question和category都有一个order_number字段.是个整

  • Postgresql查询效率计算初探

    摘要 关系数据库很重要的一个方面是查询速度.查询速度的好坏,直接影响一个系统的好坏. 查询速度一般需要通过查询规划来窥视执行的过程. 查询路径会选择查询代价最低的路径执行.而这个代价是怎么算出来的呢. 主要关注的参数和表 参数:来自postgresql.conf文件,可以通过show 来查看 seq_page_cost = 1.0 # measured on an arbitrary scale random_page_cost = 4.0 # same scale as above cpu_t

  • 探讨select in 在postgresql的效率问题

    在知乎上看到这样一个问题: MySQL 查询 select * from table where id in (几百或几千个 id) 如何提高效率?修改 电商网站,一个商品属性表,几十万条记录,80M,索引只有主键id,做这样的查询如何提高效率? select * from table where id in (几百或几千个id) 这些id没啥规律,分散的.... 看了一下答案,感觉有好多不靠谱的,但是口说无凭,所以在我的电脑上写了几个查询测试一下.我用的是Postgresql9.4,但感觉my

  • MySQL提升大量数据查询效率的优化神器

    目录 前言 查看SQL执行频率 定位低效率执行SQL explain分析执行计划 trace分析优化器执行计划 使用索引优化 SQL优化 大量插入数据 优化insert语句 优化order by语句 2.两种排序方式 3.Filesort 的优化 优化group by 子查询优化 limit优化 前言 在应用的的开发过程中,由于初期数据量小,开发人员写 SQL 语句时更重视功能上的实现,但是当应用系统正式上线后,随着生产数据量的急剧增长,很多 SQL 语句开始逐渐显露出性能问题,对生产的影响也越

  • Access使用查询--1.1. 用选择查询建立计算字段

    1. 用选择查询建立计算字段 建一个选择查询,添加"车队运输"表,将其所有字段拖拽到设计网格中.如图一所示,只要在空白列中填写"净重:毛重-皮重",系统会自动为"毛重"和"皮重"加上"[   ]",表示它们是字段.把这个查询保存为"车队运输查询". 下面的表格就是刚制作的车队运输查询,净重是自动计算的: 车队运输查询 司机 货物类别 毛重 皮重 净重 李大方 其他 75.00 25.00

  • mysql in语句子查询效率慢的优化技巧示例

    表结构如下,文章只有690篇. 文章表article(id,title,content) 标签表tag(tid,tag_name) 标签文章中间表article_tag(id,tag_id,article_id) 其中有个标签的tid是135,查询标签tid是135的文章列表. 690篇文章,用以下的语句查询,奇慢: select id,title from article where id in( select article_id from article_tag where tag_id=

  • MySQL查询优化:LIMIT 1避免全表扫描提高查询效率

    在某些情况下,如果明知道查询结果只有一个,SQL语句中使用LIMIT 1会提高查询效率. 例如下面的用户表(主键id,邮箱,密码): 复制代码 代码如下: create table t_user( id int primary key auto_increment, email varchar(255), password varchar(255) ); 每个用户的email是唯一的,如果用户使用email作为用户名登陆的话,就需要查询出email对应的一条记录. SELECT * FROM t

  • mysql中提高Order by语句查询效率的两个思路分析

    因为可能需要对数据库的记录进行重新排序.在这篇文章中,笔者就谈谈提高Order By语句查询效率的两个思路,以供大家参考. 在MySQL数据库中,Order by语句的使用频率是比较高的.但是众所周知,在使用这个语句时,往往会降低数据查询的性能.因为可能需要对数据库的记录进行重新排序.在这篇文章中,笔者就谈谈提高Order By语句查询效率的两个思路,以供大家参考. 498)this.width=498;" border=0> 一.建议使用一个索引来满足Order By子句. 在条件允许的

  • MySql数据库单表查询与多表连接查询效率对比

    这段时间在做项目的过程中,遇到一个模块,数据之间的联系很复杂,在建表的时候就很纠结,到底该怎么去处理这些复杂的数据呢,是单表查询,然后在业务层去处理数据间的关系,还是直接通过多表连接查询来处理数据关系呢? 通过查阅资料和阅读博客,有以下两个回答: 一.<高性能mysql>中的回答 很多高性能的应用都会对关联查询进行分解.简单地,可以对每个表进行一次单表查询,然后将结果在应用程序中进行关联.例如,下面这个查询: select * from tag join tag_post on tag_pos

  • 提高MySQL深分页查询效率的三种方案

    开发经常遇到分页查询的需求,但是当翻页过多的时候,就会产生深分页,导致查询效率急剧下降.有没有什么办法,能解决深分页的问题呢?本文总结了三种优化方案,查询效率直接提升10倍,一起学习一下. 开发经常遇到分页查询的需求,但是当翻页过多的时候,就会产生深分页,导致查询效率急剧下降. 有没有什么办法,能解决深分页的问题呢? 本文总结了三种优化方案,查询效率直接提升10倍,一起学习一下. 1. 准备数据 先创建一张用户表,只在create_time字段上加索引: CREATE TABLE `user`

  • 提高MySQL 查询效率的三个技巧第1/2页

    MySQL由于它本身的小巧和操作的高效, 在数据库应用中越来越多的被采用.我在开发一个P2P应用的时候曾经使用MySQL来保存P2P节点,由于P2P的应用中,结点数动辄上万个,而且节点变化频繁,因此一定要保持查询和插入的高效.以下是我在使用过程中做的提高效率的三个有效的尝试. l        使用statement进行绑定查询 使用statement可以提前构建查询语法树,在查询时不再需要构建语法树就直接查询.因此可以很好的提高查询的效率. 这个方法适合于查询条件固定但查询非常频繁的场合. 使

随机推荐