Faster alternative to count value from 2 queries and select with WITH I have a query which I have to make it run faster.
This is my best shot.
Any recommendations that I can improve this?

WITH cm 
     AS (SELECT Count(*) AS count_messages 
         FROM   messages AS m 
         WHERE  EXISTS (SELECT 1 
                        FROM   order_items AS o 
                               inner join orders ox 
                                       ON ox.order_id = o.order_id 
                        WHERE  m.product_id = o.product_id 
                               AND m.message_type = 0 
                               AND m.seller_id IN( 3, 2, 6, 1, 9 ) 
                               AND current_date &gt;= ox.order_creation_date)), 
     co 
     AS (SELECT Count(*) AS count_order_items 
         FROM   order_items AS o 
         WHERE  EXISTS (SELECT 1 
                        FROM   messages AS m 
                               inner join orders oy 
                                       ON oy.order_id = o.order_id 
                        WHERE  m.product_id = o.product_id 
                               AND m.message_type = 0 
                               AND m.seller_id IN( 3, 2, 6, 1, 9 ) 
                               AND current_date &gt;= oy.order_creation_date)) 
SELECT cm.count_messages :: DECIMAL / co.count_order_items :: DECIMAL * 100 AS 
       result 
FROM   cm, 
       co
It's a bit tricky to do query rewriting without knowing any keys etc, but if I'm not mistaken cm can be rewritten as:

SELECT Count(distinct m.message_id) AS count_messages
FROM   messages AS m
JOIN   order_items AS o
    ON m.product_id = o.product_id
JOIN   orders ox
    ON ox.order_id = o.order_id                               
WHERE m.message_type = 0
  AND m.seller_id IN( 3, 2, 6, 1, 9 )                               
  AND current_date &gt;= ox.order_creation_date


using the same technique and the fact that A |x| B &lt;=&gt; B |x| A give us:

SELECT Count(distinct o.order_item_id) AS count_order_items
FROM   messages AS m
JOIN   order_items AS o
    ON m.product_id = o.product_id
JOIN   orders ox
    ON ox.order_id = o.order_id
WHERE m.message_type = 0
  AND m.seller_id IN( 3, 2, 6, 1, 9 )
  AND current_date &gt;= ox.order_creation_date


for co. This can be combined to:

SELECT 100*Count(distinct m.message_id) :: Decimal 
         / Count(distinct o.order_item_id) :: Decimal 
FROM   messages AS m
JOIN   order_items AS o
    ON m.product_id = o.product_id
JOIN   orders ox
    ON ox.order_id = o.order_id
WHERE m.message_type = 0
  AND m.seller_id IN( 3, 2, 6, 1, 9 )
  AND current_date &gt;= ox.order_creation_date