Можно ли как-то оптимизировать этот запрос ?
SELECT Prop.*, coalesce("allUnits".count, 0) AS "countAllUnits", coalesce("vacantUnits".count, 0) AS "countVacantUnits"
FROM "Property" AS Prop
JOIN
(
SELECT "propertyId", COUNT(*) AS count
FROM "Unit"
GROUP BY "propertyId"
) AS "allUnits" ON Prop."id" = "allUnits"."propertyId"
JOIN
(
SELECT "propertyId", COUNT(*) AS count
FROM "Unit"
WHERE "Unit".status = 'Vacant'
GROUP BY "propertyId"
) AS "vacantUnits" ON Prop."id" = "vacantUnits"."propertyId"
WHERE Prop."userId" IN (
SELECT id FROM "User" WHERE "companyId" = 200001
)
ORDER BY Prop."userId" ASC LIMIT 10 OFFSET 0
Вот EXPLAIN ANALYZE
QUERY PLAN
Merge Left Join (cost=1328267.49..1608392.69 rows=1 width=538) (actual time=8829.697..9516.500 rows=1 loops=1)
Merge Cond: (prop.id = "Unit_1"."propertyId")
-> Merge Join (cost=640598.57..670979.83 rows=1 width=530) (actual time=6533.859..7220.661 rows=1 loops=1)
Merge Cond: (prop.id = "Unit"."propertyId")
-> Sort (cost=24.82..24.83 rows=2 width=522) (actual time=0.405..0.406 rows=2 loops=1)
Sort Key: prop.id
Sort Method: quicksort Memory: 27kB
-> Nested Loop (cost=0.85..24.81 rows=2 width=522) (actual time=0.339..0.380 rows=19 loops=1)
-> Index Scan using "userCompanyIdIndex" on "User" (cost=0.42..8.44 rows=1 width=4) (actual time=0.268..0.268 rows=1 loops=1)
Index Cond: ("companyId" = 200001)
-> Index Scan using "propertyUserIdIndex" on "Property" prop (cost=0.43..16.34 rows=3 width=522) (actual time=0.068..0.101 rows=19 loops=1)
Index Cond: ("userId" = "User".id)
-> GroupAggregate (cost=640573.75..661192.81 rows=780974 width=12) (actual time=6492.785..7173.418 rows=837901 loops=1)
Group Key: "Unit"."propertyId"
-> Sort (cost=640573.75..644843.52 rows=1707910 width=4) (actual time=6492.768..6857.919 rows=1682619 loops=1)
Sort Key: "Unit"."propertyId"
Sort Method: external merge Disk: 23152kB
-> Bitmap Heap Scan on "Unit" (cost=31972.73..440420.61 rows=1707910 width=4) (actual time=392.013..5277.053 rows=1682619 loops=1)
Recheck Cond: ((status)::text = 'Vacant'::text)
Rows Removed by Index Recheck: 2854995
Heap Blocks: exact=55840 lossy=329108
-> Bitmap Index Scan on "unitStatusIndex" (cost=0.00..31545.76 rows=1707910 width=0) (actual time=369.984..369.984 rows=1682619 loops=1)
Index Cond: ((status)::text = 'Vacant'::text)
-> Finalize GroupAggregate (cost=687668.91..926713.97 rows=855910 width=12) (actual time=2106.042..2289.771 rows=49830 loops=1)
Group Key: "Unit_1"."propertyId"
-> Gather Merge (cost=687668.91..909595.77 rows=1711820 width=12) (actual time=2106.020..2263.616 rows=126993 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial GroupAggregate (cost=686668.89..711009.24 rows=855910 width=12) (actual time=2037.828..2112.141 rows=43246 loops=3)
Group Key: "Unit_1"."propertyId"
-> Sort (cost=686668.89..691929.31 rows=2104167 width=4) (actual time=2037.818..2076.664 rows=97680 loops=3)
Sort Key: "Unit_1"."propertyId"
Sort Method: external merge Disk: 22848kB
-> Parallel Seq Scan on "Unit" "Unit_1" (cost=0.00..408140.67 rows=2104167 width=4) (actual time=0.029..785.149 rows=1683334 loops=3)
Planning time: 3.233 ms
Execution time: 9538.732 ms