postgresql - 我的索引或列类型是否会减慢我的查询速度?

时间:2015-09-12 16:56:24

标签: postgresql postgresql-performance

我有一个我在本地创建的表,在一个有大约400万行(最初是文本文件)的数据集上使用PG的一些窗口函数。每行对应一个客户订单。

CREATE TABLE orders
(
  orderid integer,
  customerid integer,
  orderdate date,
  status text,
  amount money,
  tax money,
  customername text,
  customerstate text

我在i7 8gb RAM Windows 8机器上本地运行数据库。我在orderid,customerid和orderdate上有btree索引(索引?)。

当我运行以下查询时,需要300秒(appx)。我希望有一些基本的调整,我可以把它缩短到一分钟,但我不是DBA。有人有提示吗?

select orderid, customername, orderdate, 
rank() OVER (PARTITION BY customername ORDER BY orderdate ASC) as cust_ord_nbr
from orders

1 个答案:

答案 0 :(得分:1)

覆盖指数

customerid分区,如@Daniel commentedinteger更小,更便宜。如果您在结果中不需要customername,请将其完全替换为customerid

多列索引可以提供帮助(例如@wildplasser commented)。如果它是(大多数)只读表,那么"覆盖"允许仅索引扫描的索引会更快 - 特别是如果包含的列很小:

CREATE INDEX orders_nbr_idx ON orders (customerid, orderdate, orderid);

只有从中获取索引扫描才能将orderid添加到索引中。如果您需要customername,请同时添加。更多:

如果它(大部分)是只读表,请执行一次昂贵的查询并将快照保存为MATERIALIZED VIEW以便重复使用...

花生

你可以做一些小事来减少内存占用。在playing column tetris之后,这将节省当前丢失到填充的每行0-7个字节:

CREATE TABLE orders (
  orderid integer,
  customerid integer,
  amount money,
  tax money,
  orderdate date,
  status text,
  customername text,
  customerstate text
  );

如果将结果写入另一个表(或MATERIALIZED VIEW),它将节省一些以类似方式优化查询。 rank()生成bigint,通过强制转换为int每行节省8个字节(4 + 4填充):

SELECT orderid, customername, orderdate
    -- orderid, customerid, orderdate  -- good enough?
     , rank() OVER (PARTITION BY customerid
                    ORDER BY orderdate)::int AS cust_ord_nbr
FROM   orders;