Good day,
I'm the DBA/infrastructure-engineer (that's what they call me, not that I'm an engineer ;() for a Mendix application, so no, I've not yet opened the modeller, just deploying the .mda with m2ee and handling the PostgreSQL database(s) :)
Below two explain analyze on a ~165GB database (including all the indexes) for a query from 6.10.10. The first is the query as issued by the Mendix app, the second contains a "order by" clause in the sub-select query. As you can see, it's 26x times faster than the query that Mendix created.
Now my questions:
1) What should I ask the developer to do to give you better information to debug/analyze this issue?
2) Anything that the developer(s) can do to get the "order by" clause added to the query?
Mendix 6.10.10 query:
aquacheckweb=# explain analyze select "field$datapoint"."soiltemperature1400","field$datapoint"."maximumdepth","field$datapoint"."powersavingsmode"
FROM "field$datapoint"
WHERE "field$datapoint"."id" IN (SELECT "c1field$datapoint_profile"."field$datapointid"
FROM "field$datapoint_profile""c1field$datapoint_profile"
WHERE "c1field$datapoint_profile"."field$profileid" = 14918173765683509)
ORDER BY "field$datapoint"."datadate" DESC,"field$datapoint"."id" DESC LIMIT 1;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=227.00..820633.93 rows=1 width=29) (actual time=7471.294..7471.294 rows=1 loops=1)
-> Nested Loop Semi Join (cost=227.00..11310950621.74 rows=13787 width=29) (actual time=7471.293..7471.293 rows=1 loops=1)
-> Index Scan Backward using "idx_field$datapoint_datadate" on "field$datapoint" (cost=113.50..53086239.37 rows=97886374 width=29) (actual time=0.009..1540.537 rows=4257689 loops=1)
-> Index Only Scan using "field$datapoint_profile_pkey" on "field$datapoint_profile""c1field$datapoint_profile" (cost=113.50..115.01 rows=1 width=8) (actual time=0.001..0.001 rows=0 loops=4257689)
Index Cond: (("field$datapointid" = "field$datapoint".id) AND ("field$profileid" = '14918173765683509'::bigint))
Heap Fetches: 1
Planning time: 0.426 ms
Execution time: 7471.326 ms
(8 rows)
The optimized query:
aquacheckweb=# explain analyze select "field$datapoint"."soiltemperature1400","field$datapoint"."maximumdepth","field$datapoint"."powersavingsmode"
FROM "field$datapoint"
WHERE "field$datapoint"."id" IN (SELECT "c1field$datapoint_profile"."field$datapointid"
FROM "field$datapoint_profile""c1field$datapoint_profile"
WHERE "c1field$datapoint_profile"."field$profileid" = 14918173765683509 order by "c1field$datapoint_profile"."field$datapointid")
ORDER BY "field$datapoint"."datadate" DESC,"field$datapoint"."id" DESC LIMIT 1;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=1661339.87..1661340.37 rows=1 width=29) (actual time=287.819..287.820 rows=1 loops=1)
-> Sort (cost=1661339.87..1668233.37 rows=13787 width=29) (actual time=287.817..287.817 rows=1 loops=1)
Sort Key: "field$datapoint".datadate DESC, "field$datapoint".id DESC
Sort Method: top-N heapsort Memory: 25kB
-> Nested Loop (cost=27953.94..1647552.87 rows=13787 width=29) (actual time=231.228..286.999 rows=4167 loops=1)
-> HashAggregate (cost=27840.44..34733.93 rows=13787 width=8) (actual time=231.152..232.457 rows=4167 loops=1)
Group Key: "c1field$datapoint_profile"."field$datapointid"
-> Index Only Scan using "idx_field$datapoint_profile_field$profile_field$datapoint" on "field$datapoint_profile""c1field$datapoint_profile" (cost=113.50..14053.44 rows=13787 width=8) (actual time=1.649..229.249 rows=4167 loops=1)
Index Cond: ("field$profileid" = '14918173765683509'::bigint)
Heap Fetches: 2837
-> Index Scan using "field$datapoint_pkey" on "field$datapoint" (cost=113.50..116.48 rows=1 width=29) (actual time=0.013..0.013 rows=1 loops=4167)
Index Cond: (id = "c1field$datapoint_profile"."field$datapointid")
Planning time: 0.390 ms
Execution time: 287.922 ms
(14 rows)
aquacheckweb=#