Store two metric sets long or wide if frequently joined?
If that's the complete situation I would merge metrics_a and metrics_b for considerably smaller storage and considerably faster and simpler queries.

Your example query could then look like this:

SELECT point_id
     , count(*) AS tot_ct
     , :lim AS lim
     , count(a00 &lt;= :lim OR NULL) AS a_ct00
     , count(a01 &lt;= :lim OR NULL) AS a_ct01
     , count(a02 &lt;= :lim OR NULL) AS a_ct02
     -- ,  ... more
     , count((a00 - b00) &gt;= 4.25 AND b00 &lt;= :lim OR NULL) w_ct00
     , count((a01 - b01) &gt;= 4.25 AND b01 &lt;= :lim OR NULL) w_ct01
     , count((a02 - b02) &gt;= 4.25 AND b02 &lt;= :lim OR NULL) w_ct02
     -- ,  ... more
     , avg(a00) AS av_a00, avg(a01) AS av_a01, avg(a02) AS av_a02  -- , ... more
FROM   metrics
WHERE  logdate BETWEEN '2017-06-01' AND '2017-07-31';



Renamed m00 to a00 and b00 etc. respectively.
Saves at least 28 bytes (tuple header + item identifier) + 8 - 16 bytes for redundant columns per row. Smaller is faster, too. See:


Configuring PostgreSQL for read performance

No join, faster query.
Shorter, simpler code.


Asides:


I shortened the count syntax. Should be about as fast. See:


For absolute performance, is SUM faster or COUNT?

Don't omit the AS keyword for column aliases. See:


Aliases with correlated subqueries

Always use standard ISO 8601 date format. No exceptions. Related:


Can&#39;t execute dynamic DDL, argument is NULL