了解 PostgreSQL 性能

Understanding of PostgreSQL performance

我有一个关于 PostgreSQL 如何执行查询的确切理解的问题。由于它是基于行的,因此您是否有像 Select * from lineitemSelect l_orderkey from lineitem 这样的性能明智的查询无关紧要?此外,为什么 Select count(*) from lineitemSelect * from lineitem 之间的测量时间存在差异,因为在这两种情况下都必须扫描完整的 table? 我正在这样衡量性能:

long starttime=System.CurrenMillis();
Statement a = conn.createStatement();
a.setFetchsize(10000);
Resultset rs = a.executeQuery(Query);
while(rs.next()){}
long endTime=System.currentMillis();
System.out.println((endTime-starttime));

我必须设置 fetchsize,否则会出现 Java 堆 Space 错误,因为 table 非常大。 此外,我正在尝试测量与水平分区 table 的差异。为此,我按 orderstatus='O' 拆分了 table 订单,得到两个具有相同大小的 tables (ordersO, ordersF)。比较查询 Select * from ordersOSelect * from orders where o_orderstatus='O' 时,我期望分区上的第一个查询只需要一半的时间,因为它只包含一半的元组?但事实并非如此,测量的时间或多或少是相等的。

提前致谢!

这里有几个问题。

SELECT col FROM tab 会比 SELECT * FROM tab 表现更好吗?

是的,会的,原因有二:

  1. PostgreSQL 不必从行中提取所有列。如果该列在列列表的前面,那显然是胜利。但我们也赢了,因为我们不必“取消烘烤”存储在 TOAST table.

    中的超大属性
  2. 你向客户端传输的数据更少,客户端处理的数据也更少。

为什么 SELCT count(*) FROM tabSELECT * FROM tab 快?

主要是因为它不必向客户端传输大量数据。此外,它必须对服务器上的每个 table 行进行较少的处理。

为什么 SELECT * FROM tab_42SELECT * FROM tab WHERE partkey = 42 一样快?

那是因为分区修剪。如果分区键在 WHERE 子句中,PostgreSQL 会将扫描限制在适当的 table 分区。