selectThe schemas are simple:
lead.score > 0,
count(*) as effort, count(distinct lead.id) as leads, count(distinct case lead.isconverted when false then lead.id end) as unconv, count(nullif(lead.isconverted, true)) as unconv_effort, from lead left outer join task on lead.id = task.whoid where not lead.isdeleted and lead.createddate between '2013-01-01' and '2013-11-01' group by lead.score > 0;
CREATE TABLE lead ( id varchar(65000) NOT NULL, score real, isconverted boolean, isdeleted boolean, createddate timestamp without time zone, ... 328 columns total ... ); CREATE TABLE task ( id varchar(65000) NOT NULL, whoid varchar(65000), ... 88 columns total ... );EXPLAIN shows nothing outrageous:
Access Path: +-GROUPBY HASH (LOCAL RESEGMENT GROUPS) [Cost: 447M, Rows: 1 (NO STATISTICS)] (PATH ID: 1) | Aggregates: count(DISTINCT lead.id), sum_of_count(*), sum_of_count(), count(DISTINCT ) | Group By: | +---> GROUPBY HASH (LOCAL RESEGMENT GROUPS) [Cost: 447M, Rows: 10K (NO STATISTICS)] (PATH ID: 2) | | Aggregates: count(*), count(CASE WHEN (lead.isconverted = true) THEN NULL::boolean ELSE lead.isconverted END) | | Group By: (lead.score > 0), lead.id, CASE lead.isconverted WHEN false THEN lead.id ELSE NULL END | | Grouping Sets: (, lead.id, , ), (, ) | | +---> JOIN HASH [RightOuter] [Cost: 437M, Rows: 6M (NO STATISTICS)] (PATH ID: 3) | | | Join Cond: (lead.id = task.whoid) | | | +-- Outer -> STORAGE ACCESS for task [Cost: 19M, Rows: 6M (NO STATISTICS)] (PATH ID: 4) | | | | Projection: task_super | | | | Materialize: task.whoid | | | | Runtime Filter: (SIP1(HashJoin): task.whoid) | | | +-- Inner -> STORAGE ACCESS for lead [Cost: 1M, Rows: 433K (NO STATISTICS)] (PATH ID: 5) | | | | Projection: lead_super | | | | Materialize: lead.id, lead.isconverted, lead.score | | | | Filter: (NOT lead.isdeleted) | | | | Filter: ((lead.createddate >= '2013-01-01 00:00:00'::timestamp) AND (lead.createddate <= '2013-11-01 00:00:00'::timestamp)) ------------------------------ ----------------------------------------------- PLAN: BASE QUERY PLAN (GraphViz Format) ----------------------------------------------- digraph G { graph [rankdir=BT, label = "BASE QUERY PLAN\nQuery: explain\nselect\n lead.score \> 0,\n count(*) as effort,\n count(distinct lead.id) as leads,\n count(distinct case lead.isconverted when false then lead.id end) as unconv,\n count(nullif(lead.isconverted, true)) as unconv_effort\nfrom lead\nleft outer join task on lead.id = task.whoid\nwhere not lead.isdeleted\n and lead.createddate between \'2013-01-01\' and \'2013-11-01\'\ngroup by lead.score \> 0;\n\nAll Nodes Vector: \n\n node[0]=v_pod_node0001 (initiator) Up\n", labelloc=t, labeljust=l ordering=out] 0[label = "Root \nOutBlk=[UncTuple(5)]", color = "green", shape = "house"]; 1[label = "NewEENode \nOutBlk=[UncTuple(5)]", color = "green", shape = "box"]; 2[label = "ParallelUnionStep: \nCombine\nUnc: Boolean(1)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Integer(8)", color = "green", shape = "box"]; 3[label = "ExprEval: \n \\n \\n \\n \\n \\nUnc: Boolean(1)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Integer(8)", color = "green", shape = "box"]; 4[label = "GroupByHash(Spill): 1 keys\nAggs:\n count(DISTINCT lead.id)\n sum_of_count(*)\n sum_of_count(\)\n count(DISTINCT \)\nUnc: Boolean(1)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Integer(8)", color = "green", shape = "box"]; 5[label = "ParallelUnionStep: \nLocally Resegment\nUnc: Boolean(1)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Integer(8)", color = "green", shape = "box"]; 6[label = "GroupByPipe(HashPrepass): 1 keys\nAggs:\n count(DISTINCT lead.id)\n sum_of_count(*)\n sum_of_count(\)\n count(DISTINCT \)\nUnc: Boolean(1)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Integer(8)", color = "green", shape = "box"]; 7[label = "ExprEval: \n (lead.score \> 0)\n lead.id\n count(*)\n count(CASE WHEN (lead.isconverted = true) THEN NULL::boolean ELSE lead.isconverted END)\n CASE lead.isconverted WHEN false THEN lead.id ELSE NULL END\nUnc: Boolean(1)\nUnc: Varchar(65000)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Varchar(65000)", color = "green", shape = "box"]; 8[label = "GroupByHash(Spill): 4 keys\nAggs:\n count(*)\n count(CASE WHEN (lead.isconverted = true) THEN NULL::boolean ELSE lead.isconverted END)\nUnc: Boolean(1)\nUnc: Varchar(65000)\nUnc: Varchar(65000)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Integer(8)", color = "green", shape = "box"]; 9[label = "ParallelUnionStep: \nLocally Resegment\nUnc: Boolean(1)\nUnc: Varchar(65000)\nUnc: Varchar(65000)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Boolean(1)", color = "green", shape = "box"]; 10[label = "ExprEval: \n (lead.score \> 0)\n lead.id\n CASE lead.isconverted WHEN false THEN lead.id ELSE NULL END\n \\n count(*)\n count(CASE WHEN (lead.isconverted = true) THEN NULL::boolean ELSE lead.isconverted END)\nUnc: Boolean(1)\nUnc: Varchar(65000)\nUnc: Varchar(65000)\nUnc: Integer(8)\nUnc: Integer(8)\nUnc: Boolean(1)", color = "green", shape = "box"]; 11[label = "GroupGeneratorStep\nkeys: 5\ngExprs: 1\nAggregates: \n count(*)\n count(CASE WHEN (lead.isconverted = true) THEN NULL::boolean ELSE lead.isconverted END)\nUnc: Boolean(1)\nUnc: Varchar(65000)\nUnc: Integer(8)\nUnc: Boolean(1)\nUnc: Varchar(65000)\nUnc: Integer(8)", color = "green", shape = "box"]; 12[label = "ExprEval: \n (lead.score \> 0)\n lead.id\n count(*)\n count(CASE WHEN (lead.isconverted = true) THEN NULL::boolean ELSE lead.isconverted END)\n CASE lead.isconverted WHEN false THEN lead.id ELSE NULL END\n 1\nUnc: Boolean(1)\nUnc: Varchar(65000)\nUnc: Integer(8)\nUnc: Boolean(1)\nUnc: Varchar(65000)\nUnc: Integer(8)", color = "green", shape = "box"]; 13[label = "ExprEval: \n (lead.score \> 0)\n lead.id\n CASE lead.isconverted WHEN false THEN lead.id ELSE NULL END\n 1\n CASE WHEN (lead.isconverted = true) THEN NULL::boolean ELSE lead.isconverted END\nUnc: Boolean(1)\nUnc: Varchar(65000)\nUnc: Varchar(65000)\nUnc: Integer(8)\nUnc: Boolean(1)", color = "green", shape = "box"]; 14[label = "Join: Hash-Join: \n(task x lead) using task_super and lead_super (PATH ID: 3)\n[RightOuter]\n\nUnc: Varchar(65000)\nUnc: Boolean(1)\nUnc: Float(8)", color = "green", shape = "box"]; 15[label = "StorageUnionStep: task_super\nUnc: Varchar(65000)", color = "purple", shape = "box"]; 16[label = "ScanStep: task_super\nSIP1(HashJoin): task.whoid\nid (not emitted)\nwhoid\nUnc: Varchar(65000)", color = "brown", shape = "box"]; 17[label = "StorageUnionStep: lead_super\nUnc: Varchar(65000)\nUnc: Boolean(1)\nUnc: Float(8)", color = "purple", shape = "box"]; 18[label = "ScanStep: lead_super\n(NOT lead.isdeleted)\n((lead.createddate \>= \'2013-01-01 00:00:00\'::timestamp) AND (lead.createddate \<= \'2013-11-01 00:00:00\'::timestamp))\nid\nisdeleted (not emitted)\ncreateddate (not emitted)\nisconverted\nscore\nUnc: Varchar(65000)\nUnc: Boolean(1)\nUnc: Float(8)", color = "brown", shape = "box"]; 1->0 [label = "V[0] C=5",color = "black",style="bold", arrowtail="inv"]; 2->1 [label = "0",color = "blue"]; 3->2 [label = "0",color = "blue"]; 4->3 [label = "0",color = "blue"]; 5->4 [label = "0",color = "blue"]; 6->5 [label = "0",color = "blue"]; 7->6 [label = "0",color = "blue"]; 8->7 [label = "0",color = "blue"]; 9->8 [label = "0",color = "blue"]; 10->9 [label = "0",color = "blue"]; 11->10 [label = "0",color = "blue"]; 12->11 [label = "0",color = "blue"]; 13->12 [label = "0",color = "blue"]; 14->13 [label = "0",color = "blue"]; 15->14 [label = "0",color = "blue"]; 16->15 [label = "0",color = "blue"]; 17->14 [label = "1",color = "blue"]; 18->17 [label = "0",color = "blue"]; } (82 rows)I also don't think I'm grokking the cost numbers because when I run the following query, it finishes in a couple seconds, which is closer to the performance I'm expecting:
select id, whoid from task order by id, whoid offset 5946020 limit 10; Access Path: +-SELECT LIMIT 10 OFFSET 6M [Cost: 915M, Rows: 10 (NO STATISTICS)] (PATH ID: 0) | Output Only: 5946030 tuples | +---> SORT [Cost: 915M, Rows: 6M (NO STATISTICS)] (PATH ID: 1) | | Order: task.id ASC, task.whoid ASC | | Output Only: 5946030 tuples | | +---> STORAGE ACCESS for task [Cost: 38M, Rows: 6M (NO STATISTICS)] (PATH ID: 2) | | | Projection: task_super | | | Materialize: task.id, task.whoidNote: I'm explicitly caring about performance without projections. These are examples of ad-hoc queries. I'm seeking query latencies on the order of several seconds.
Thanks for any answers!
take less time than half an hour.