我有以下查询/视图:
CREATE OR REPLACE VIEW "SumAndSalesPerCountryYear" AS
SELECT date_part('year'::text, "Invoice"."InvoiceDate") AS year,
"Invoice"."BillingCountry" AS country,
sum("Invoice"."Total") AS total
FROM "Invoice"
GROUP BY date_part('year'::text, "Invoice"."InvoiceDate"), "Invoice"."BillingCountry"
ORDER BY date_part('year'::text, "Invoice"."InvoiceDate") DESC, sum("Invoice"."Total") DESC;
我的表格结构如下:
CREATE TABLE "Invoice"
(
"InvoiceId" integer NOT NULL,
"CustomerId" integer NOT NULL,
"InvoiceDate" timestamp without time zone NOT NULL,
"BillingAddress" character varying(70),
"BillingCity" character varying(40),
"BillingState" character varying(40),
"BillingCountry" character varying(40),
"BillingPostalCode" character varying(10),
"Total" numeric(10,2) NOT NULL,
CONSTRAINT "PK_Invoice" PRIMARY KEY ("InvoiceId"),
CONSTRAINT "FK_InvoiceCustomerId" FOREIGN KEY ("CustomerId")
REFERENCES "Customer" ("CustomerId") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
当前的执行计划是
Sort (cost=33.65..34.54 rows=354 width=21) (actual time=0.691..0.698 rows=101 loops=1)"
Sort Key: (date_part('year'::text, "Invoice"."InvoiceDate")), (sum("Invoice"."Total"))
Sort Method: quicksort Memory: 32kB
-> HashAggregate (cost=14.24..18.67 rows=354 width=21) (actual time=0.540..0.567 rows=101 loops=1)
-> Seq Scan on "Invoice" (cost=0.00..11.15 rows=412 width=21) (actual time=0.015..0.216 rows=412 loops=1)
Total runtime: 0.753 ms
我的任务是使用索引优化查询,但我想不出使用索引来优化聚合结果的方法。
答案 0 :(得分:2)
您可以尝试通过“SET enable_hashagg to OFF”惩罚Hashagg,但可能对于小数据,索引没有任何好处..在这个用例中 - hashagg通常是最快速的聚合方法和排序32kB是很快。
但是..你正在尝试在412行的表上进行性能基准测试。这是无稽之谈。任何对性能的考虑都与数据有关,这些数据的大小与生产使用2。3年有关。
答案 1 :(得分:1)
正如Pavel,Ramfjord和马所指出的,使用索引对于这么少量的数据几乎没用。它非常小,以至于Postgres读取磁盘页面或处理内存中的所有内容的速度更快。
此外,您已经为查询提供了最佳计划。您要求Postgres计算整个表的聚合并按特定顺序返回。 Postgres通过计算内存中的聚合而不需要首先对数据进行排序,通过使用哈希分配中间结果来继续进行;然后根据您的标准对少量结果进行排序。