{"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970855084", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970855084, "node_id": "IC_kwDOBm6k_c453hKs", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T23:41:46Z", "updated_at": "2021-11-16T23:41:46Z", "author_association": "OWNER", "body": "Conclusion: using a giant convoluted CTE and UNION ALL query to attempt to calculate facets at the same time as retrieving rows is a net LOSS for performance! Very surprised to see that.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970853917", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970853917, "node_id": "IC_kwDOBm6k_c453g4d", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T23:41:01Z", "updated_at": "2021-11-16T23:41:01Z", "author_association": "OWNER", "body": "One very interesting difference between the two: on the single giant query page:\r\n\r\n```json\r\n{\r\n \"request_duration_ms\": 376.4317020000476,\r\n \"sum_trace_duration_ms\": 370.0828700000329,\r\n \"num_traces\": 5\r\n}\r\n```\r\nAnd on the page that uses separate queries:\r\n```json\r\n{\r\n \"request_duration_ms\": 819.012272000009,\r\n \"sum_trace_duration_ms\": 201.52852100000018,\r\n \"num_traces\": 19\r\n}\r\n```\r\nThe separate pages page takes 819ms total to render the page, but spends 201ms across 19 SQL queries.\r\n\r\nThe single big query takes 376ms total to render the page, spending 370ms in 5 queries\r\n\r\n
Those 5 queries, if you're interested\r\n\r\n```sql\r\nselect database_name, schema_version from databases\r\nPRAGMA schema_version\r\nPRAGMA schema_version\r\nexplain with cte as (\\r\\n select rowid, date, county, state, fips, cases, deaths\\r\\n from ny_times_us_counties\\r\\n),\\r\\ntruncated as (\\r\\n select null as _facet, null as facet_name, null as facet_count, rowid, date, county, state, fips, cases, deaths\\r\\n from cte order by date desc limit 4\\r\\n),\\r\\nstate_facet as (\\r\\n select 'state' as _facet, state as facet_name, count(*) as facet_count,\\r\\n null, null, null, null, null, null, null\\r\\n from cte group by facet_name order by facet_count desc limit 3\\r\\n),\\r\\nfips_facet as (\\r\\n select 'fips' as _facet, fips as facet_name, count(*) as facet_count,\\r\\n null, null, null, null, null, null, null\\r\\n from cte group by facet_name order by facet_count desc limit 3\\r\\n),\\r\\ncounty_facet as (\\r\\n select 'county' as _facet, county as facet_name, count(*) as facet_count,\\r\\n null, null, null, null, null, null, null\\r\\n from cte group by facet_name order by facet_count desc limit 3\\r\\n)\\r\\nselect * from truncated\\r\\nunion all select * from state_facet\\r\\nunion all select * from fips_facet\\r\\nunion all select * from county_facet\r\nwith cte as (\\r\\n select rowid, date, county, state, fips, cases, deaths\\r\\n from ny_times_us_counties\\r\\n),\\r\\ntruncated as (\\r\\n select null as _facet, null as facet_name, null as facet_count, rowid, date, county, state, fips, cases, deaths\\r\\n from cte order by date desc limit 4\\r\\n),\\r\\nstate_facet as (\\r\\n select 'state' as _facet, state as facet_name, count(*) as facet_count,\\r\\n null, null, null, null, null, null, null\\r\\n from cte group by facet_name order by facet_count desc limit 3\\r\\n),\\r\\nfips_facet as (\\r\\n select 'fips' as _facet, fips as facet_name, count(*) as facet_count,\\r\\n null, null, null, null, null, null, null\\r\\n from cte group by facet_name order by facet_count desc limit 3\\r\\n),\\r\\ncounty_facet as (\\r\\n select 'county' as _facet, county as facet_name, count(*) as facet_count,\\r\\n null, null, null, null, null, null, null\\r\\n from cte group by facet_name order by facet_count desc limit 3\\r\\n)\\r\\nselect * from truncated\\r\\nunion all select * from state_facet\\r\\nunion all select * from fips_facet\\r\\nunion all select * from county_facet\r\n```\r\n
\r\n\r\nAll of that additional non-SQL overhead must be stuff relating to Python and template rendering code running on the page. I'm really surprised at how much overhead that is! This is worth researching separately.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970845844", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970845844, "node_id": "IC_kwDOBm6k_c453e6U", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T23:35:38Z", "updated_at": "2021-11-16T23:35:38Z", "author_association": "OWNER", "body": "I tried adding `cases > 10000` but the SQL query now takes too long - so moving this to my laptop.\r\n\r\n```\r\ncd /tmp\r\nwget https://covid-19.datasettes.com/covid.db\r\ndatasette covid.db \\\r\n --setting facet_time_limit_ms 10000 \\\r\n --setting sql_time_limit_ms 10000 \\\r\n --setting trace_debug 1\r\n```\r\n`http://127.0.0.1:8006/covid/ny_times_us_counties?_trace=1&_facet_size=3&_size=2&cases__gt=10000` shows in the traces:\r\n\r\n```json\r\n[\r\n {\r\n \"type\": \"sql\",\r\n \"start\": 12.693033525,\r\n \"end\": 12.694056904,\r\n \"duration_ms\": 1.0233789999993803,\r\n \"traceback\": [\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/views/base.py\\\", line 262, in get\\n return await self.view_get(\\n\",\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/views/base.py\\\", line 477, in view_get\\n response_or_template_contexts = await self.data(\\n\",\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/views/table.py\\\", line 705, in data\\n results = await db.execute(sql, params, truncate=True, **extra_args)\\n\"\r\n ],\r\n \"database\": \"covid\",\r\n \"sql\": \"select rowid, date, county, state, fips, cases, deaths from ny_times_us_counties where \\\"cases\\\" > :p0 order by rowid limit 3\",\r\n \"params\": {\r\n \"p0\": 10000\r\n }\r\n },\r\n {\r\n \"type\": \"sql\",\r\n \"start\": 12.694285093,\r\n \"end\": 12.814936275,\r\n \"duration_ms\": 120.65118200000136,\r\n \"traceback\": [\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/views/base.py\\\", line 262, in get\\n return await self.view_get(\\n\",\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/views/base.py\\\", line 477, in view_get\\n response_or_template_contexts = await self.data(\\n\",\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/views/table.py\\\", line 723, in data\\n count_rows = list(await db.execute(count_sql, from_sql_params))\\n\"\r\n ],\r\n \"database\": \"covid\",\r\n \"sql\": \"select count(*) from ny_times_us_counties where \\\"cases\\\" > :p0\",\r\n \"params\": {\r\n \"p0\": 10000\r\n }\r\n },\r\n {\r\n \"type\": \"sql\",\r\n \"start\": 12.818812089,\r\n \"end\": 12.851172544,\r\n \"duration_ms\": 32.360455000000954,\r\n \"traceback\": [\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/views/table.py\\\", line 856, in data\\n suggested_facets.extend(await facet.suggest())\\n\",\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/facets.py\\\", line 164, in suggest\\n distinct_values = await self.ds.execute(\\n\",\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/app.py\\\", line 634, in execute\\n return await self.databases[db_name].execute(\\n\"\r\n ],\r\n \"database\": \"covid\",\r\n \"sql\": \"select county, count(*) as n from (\\n select rowid, date, county, state, fips, cases, deaths from ny_times_us_counties where \\\"cases\\\" > :p0 \\n ) where county is not null\\n group by county\\n limit 4\",\r\n \"params\": {\r\n \"p0\": 10000\r\n }\r\n },\r\n {\r\n \"type\": \"sql\",\r\n \"start\": 12.851418868,\r\n \"end\": 12.871268359,\r\n \"duration_ms\": 19.84949100000044,\r\n \"traceback\": [\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/views/table.py\\\", line 856, in data\\n suggested_facets.extend(await facet.suggest())\\n\",\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/facets.py\\\", line 164, in suggest\\n distinct_values = await self.ds.execute(\\n\",\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/app.py\\\", line 634, in execute\\n return await self.databases[db_name].execute(\\n\"\r\n ],\r\n \"database\": \"covid\",\r\n \"sql\": \"select state, count(*) as n from (\\n select rowid, date, county, state, fips, cases, deaths from ny_times_us_counties where \\\"cases\\\" > :p0 \\n ) where state is not null\\n group by state\\n limit 4\",\r\n \"params\": {\r\n \"p0\": 10000\r\n }\r\n },\r\n {\r\n \"type\": \"sql\",\r\n \"start\": 12.871497655,\r\n \"end\": 12.897715027,\r\n \"duration_ms\": 26.217371999999628,\r\n \"traceback\": [\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/views/table.py\\\", line 856, in data\\n suggested_facets.extend(await facet.suggest())\\n\",\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/facets.py\\\", line 164, in suggest\\n distinct_values = await self.ds.execute(\\n\",\r\n \" File \\\"/usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/datasette/app.py\\\", line 634, in execute\\n return await self.databases[db_name].execute(\\n\"\r\n ],\r\n \"database\": \"covid\",\r\n \"sql\": \"select fips, count(*) as n from (\\n select rowid, date, county, state, fips, cases, deaths from ny_times_us_counties where \\\"cases\\\" > :p0 \\n ) where fips is not null\\n group by fips\\n limit 4\",\r\n \"params\": {\r\n \"p0\": 10000\r\n }\r\n }\r\n]\r\n```\r\nSo that's:\r\n```\r\nfetch rows: 1.0233789999993803 ms\r\ncount: 120.65118200000136 ms\r\nfacet county: 32.360455000000954 ms\r\nfacet state: 19.84949100000044 ms\r\nfacet fips: 26.217371999999628 ms\r\n```\r\n= 200.1 ms total\r\n\r\nCompared to: `http://127.0.0.1:8006/covid?sql=with+cte+as+(%0D%0A++select+rowid%2C+date%2C+county%2C+state%2C+fips%2C+cases%2C+deaths%0D%0A++from+ny_times_us_counties%0D%0A)%2C%0D%0Atruncated+as+(%0D%0A++select+null+as+_facet%2C+null+as+facet_name%2C+null+as+facet_count%2C+rowid%2C+date%2C+county%2C+state%2C+fips%2C+cases%2C+deaths%0D%0A++from+cte+order+by+date+desc+limit+4%0D%0A)%2C%0D%0Astate_facet+as+(%0D%0A++select+%27state%27+as+_facet%2C+state+as+facet_name%2C+count(*)+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A)%2C%0D%0Afips_facet+as+(%0D%0A++select+%27fips%27+as+_facet%2C+fips+as+facet_name%2C+count(*)+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A)%2C%0D%0Acounty_facet+as+(%0D%0A++select+%27county%27+as+_facet%2C+county+as+facet_name%2C+count(*)+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A)%0D%0Aselect+*+from+truncated%0D%0Aunion+all+select+*+from+state_facet%0D%0Aunion+all+select+*+from+fips_facet%0D%0Aunion+all+select+*+from+county_facet&_trace=1`\r\n\r\nWhich is 353ms total.\r\n\r\nThe separate queries ran faster! Really surprising result there.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970828568", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970828568, "node_id": "IC_kwDOBm6k_c453asY", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T23:27:11Z", "updated_at": "2021-11-16T23:27:11Z", "author_association": "OWNER", "body": "One last experiment: I'm going to try running an expensive query in the CTE portion.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970827674", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970827674, "node_id": "IC_kwDOBm6k_c453aea", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T23:26:58Z", "updated_at": "2021-11-16T23:26:58Z", "author_association": "OWNER", "body": "With trace.\r\n\r\nhttps://covid-19.datasettes.com/covid/ny_times_us_counties?_trace=1&_facet_size=3&_size=2&_trace=1 shows the following:\r\n\r\n```\r\nfetch rows: 0.41762600005768036 ms\r\nfacet state: 284.30423800000426 ms\r\nfacet county: 273.2565999999679 ms\r\nfacet fips: 197.80996999998024 ms\r\n```\r\n= 755.78843400001ms total\r\n\r\nIt didn't run a count because that's the homepage and the count is cached. So I dropped the count from the query and ran it:\r\n\r\nhttps://covid-19.datasettes.com/covid?sql=with+cte+as+(%0D%0A++select+rowid%2C+date%2C+county%2C+state%2C+fips%2C+cases%2C+deaths%0D%0A++from+ny_times_us_counties%0D%0A)%2C%0D%0Atruncated+as+(%0D%0A++select+null+as+_facet%2C+null+as+facet_name%2C+null+as+facet_count%2C+rowid%2C+date%2C+county%2C+state%2C+fips%2C+cases%2C+deaths%0D%0A++from+cte+order+by+date+desc+limit+4%0D%0A)%2C%0D%0Astate_facet+as+(%0D%0A++select+%27state%27+as+_facet%2C+state+as+facet_name%2C+count(*)+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A)%2C%0D%0Afips_facet+as+(%0D%0A++select+%27fips%27+as+_facet%2C+fips+as+facet_name%2C+count(*)+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A)%2C%0D%0Acounty_facet+as+(%0D%0A++select+%27county%27+as+_facet%2C+county+as+facet_name%2C+count(*)+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A)%0D%0Aselect+*+from+truncated%0D%0Aunion+all+select+*+from+state_facet%0D%0Aunion+all+select+*+from+fips_facet%0D%0Aunion+all+select+*+from+county_facet&_trace=1\r\n\r\nShows 649.4359889999259 ms for the query - compared to 755.78843400001ms for the separate. So it saved about 100ms.\r\n\r\nStill not a huge difference though!\r\n\r\n\r\n\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970780866", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970780866, "node_id": "IC_kwDOBm6k_c453PDC", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T23:01:57Z", "updated_at": "2021-11-16T23:01:57Z", "author_association": "OWNER", "body": "One disadvantage to this approach: if you have a SQL time limit of 1s and it takes 0.9s to return the rows but then 0.5s to calculate each of the requested facets the entire query will exceed the time limit.\r\n\r\nCould work around this by catching that error and then re-running the query just for the rows, but that would result in the user having to wait longer for the results.\r\n\r\nCould try to remember if that has happened using an in-memory Python data structure and skip the faceting optimization if it's caused problems in the past? That seems a bit gross.\r\n\r\nMaybe this becomes an opt-in optimization you can request in your `metadata.json` setting for that table, which massively increases the time limit? That's a bit weird too - now there are two separate implementations of the faceting logic, which had better have a REALLY big pay-off to be worth maintaining.\r\n\r\nWhat if we kept the query that returns the rows to be displayed on the page separate from the facets, but then executed all of the facets together using this method such that the `cte` only (presumably) has to be calculated once? That would still lead to multiple facets potentially exceeding the SQL time limit when single facets would not have.\r\n\r\nMaybe a better optimization would be to move facets to happening via `fetch()` calls from the client, so the user gets to see their rows instantly and the facets then appear as and when they are available (though it would cause page jank).\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970766486", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970766486, "node_id": "IC_kwDOBm6k_c453LiW", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T22:52:56Z", "updated_at": "2021-11-16T22:56:07Z", "author_association": "OWNER", "body": "https://covid-19.datasettes.com/covid is 805.2MB\r\n\r\nhttps://covid-19.datasettes.com/covid/ny_times_us_counties?_trace=1&_facet_size=3&_size=2\r\n\r\nEquivalent SQL:\r\n\r\nhttps://covid-19.datasettes.com/covid?sql=with+cte+as+%28%0D%0A++select+rowid%2C+date%2C+county%2C+state%2C+fips%2C+cases%2C+deaths%0D%0A++from+ny_times_us_counties%0D%0A%29%2C%0D%0Atruncated+as+%28%0D%0A++select+null+as+_facet%2C+null+as+facet_name%2C+null+as+facet_count%2C+rowid%2C+date%2C+county%2C+state%2C+fips%2C+cases%2C+deaths%0D%0A++from+cte+order+by+date+desc+limit+4%0D%0A%29%2C%0D%0Astate_facet+as+%28%0D%0A++select+%27state%27+as+_facet%2C+state+as+facet_name%2C+count%28*%29+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A%29%2C%0D%0Afips_facet+as+%28%0D%0A++select+%27fips%27+as+_facet%2C+fips+as+facet_name%2C+count%28*%29+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A%29%2C%0D%0Acounty_facet+as+%28%0D%0A++select+%27county%27+as+_facet%2C+county+as+facet_name%2C+count%28*%29+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A%29%2C%0D%0Atotal_count+as+%28%0D%0A++select+%27COUNT%27+as+_facet%2C+%27%27+as+facet_name%2C+count%28*%29+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte%0D%0A%29%0D%0Aselect+*+from+truncated%0D%0Aunion+all+select+*+from+state_facet%0D%0Aunion+all+select+*+from+fips_facet%0D%0Aunion+all+select+*+from+county_facet%0D%0Aunion+all+select+*+from+total_count\r\n\r\n```sql\r\nwith cte as (\r\n select rowid, date, county, state, fips, cases, deaths\r\n from ny_times_us_counties\r\n),\r\ntruncated as (\r\n select null as _facet, null as facet_name, null as facet_count, rowid, date, county, state, fips, cases, deaths\r\n from cte order by date desc limit 4\r\n),\r\nstate_facet as (\r\n select 'state' as _facet, state as facet_name, count(*) as facet_count,\r\n null, null, null, null, null, null, null\r\n from cte group by facet_name order by facet_count desc limit 3\r\n),\r\nfips_facet as (\r\n select 'fips' as _facet, fips as facet_name, count(*) as facet_count,\r\n null, null, null, null, null, null, null\r\n from cte group by facet_name order by facet_count desc limit 3\r\n),\r\ncounty_facet as (\r\n select 'county' as _facet, county as facet_name, count(*) as facet_count,\r\n null, null, null, null, null, null, null\r\n from cte group by facet_name order by facet_count desc limit 3\r\n),\r\ntotal_count as (\r\n select 'COUNT' as _facet, '' as facet_name, count(*) as facet_count,\r\n null, null, null, null, null, null, null\r\n from cte\r\n)\r\nselect * from truncated\r\nunion all select * from state_facet\r\nunion all select * from fips_facet\r\nunion all select * from county_facet\r\nunion all select * from total_count\r\n```\r\n\r\n_facet | facet_name | facet_count | rowid | date | county | state | fips | cases | deaths\r\n-- | -- | -- | -- | -- | -- | -- | -- | -- | --\r\n\u00a0 | \u00a0 | \u00a0 | 1917344 | 2021-11-15 | Autauga | Alabama | 1001 | 10407 | 154\r\n\u00a0 | \u00a0 | \u00a0 | 1917345 | 2021-11-15 | Baldwin | Alabama | 1003 | 37875 | 581\r\n\u00a0 | \u00a0 | \u00a0 | 1917346 | 2021-11-15 | Barbour | Alabama | 1005 | 3648 | 79\r\n\u00a0 | \u00a0 | \u00a0 | 1917347 | 2021-11-15 | Bibb | Alabama | 1007 | 4317 | 92\r\nstate | Texas | 148028 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nstate | Georgia | 96249 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nstate | Virginia | 79315 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nfips | \u00a0 | 17580 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nfips | 53061 | 665 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nfips | 17031 | 662 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\ncounty | Washington | 18666 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\ncounty | Unknown | 15840 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\ncounty | Jefferson | 15637 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nCOUNT | \u00a0 | 1920593 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970770304", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970770304, "node_id": "IC_kwDOBm6k_c453MeA", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T22:55:19Z", "updated_at": "2021-11-16T22:55:19Z", "author_association": "OWNER", "body": "(One thing I really like about this pattern is that it should work exactly the same when used to facet the results of arbitrary SQL queries as it does when faceting results from the table page.)", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970767952", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970767952, "node_id": "IC_kwDOBm6k_c453L5Q", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T22:53:52Z", "updated_at": "2021-11-16T22:53:52Z", "author_association": "OWNER", "body": "It's going to take another 15 minutes for the build to finish and deploy the version with `_trace=1`: https://github.com/simonw/covid-19-datasette/actions/runs/1469150112", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970758179", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970758179, "node_id": "IC_kwDOBm6k_c453Jgj", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T22:47:38Z", "updated_at": "2021-11-16T22:47:38Z", "author_association": "OWNER", "body": "Trace now enabled: https://global-power-plants.datasettes.com/global-power-plants/global-power-plants?_facet_size=3&_size=2&_nocount=1&_trace=1\r\n\r\nHere are the relevant traces:\r\n```json\r\n[\r\n {\r\n \"type\": \"sql\",\r\n \"start\": 31.214430154,\r\n \"end\": 31.214817089,\r\n \"duration_ms\": 0.3869350000016425,\r\n \"traceback\": [\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/views/base.py\\\", line 262, in get\\n return await self.view_get(\\n\",\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/views/base.py\\\", line 477, in view_get\\n response_or_template_contexts = await self.data(\\n\",\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/views/table.py\\\", line 705, in data\\n results = await db.execute(sql, params, truncate=True, **extra_args)\\n\"\r\n ],\r\n \"database\": \"global-power-plants\",\r\n \"sql\": \"select rowid, country, country_long, name, gppd_idnr, capacity_mw, latitude, longitude, primary_fuel, other_fuel1, other_fuel2, other_fuel3, commissioning_year, owner, source, url, geolocation_source, wepp_id, year_of_capacity_data, generation_gwh_2013, generation_gwh_2014, generation_gwh_2015, generation_gwh_2016, generation_gwh_2017, generation_data_source, estimated_generation_gwh from [global-power-plants] order by rowid limit 3\",\r\n \"params\": {}\r\n },\r\n {\r\n \"type\": \"sql\",\r\n \"start\": 31.215234586,\r\n \"end\": 31.220110342,\r\n \"duration_ms\": 4.875756000000564,\r\n \"traceback\": [\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/views/table.py\\\", line 760, in data\\n ) = await facet.facet_results()\\n\",\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/facets.py\\\", line 212, in facet_results\\n facet_rows_results = await self.ds.execute(\\n\",\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/app.py\\\", line 634, in execute\\n return await self.databases[db_name].execute(\\n\"\r\n ],\r\n \"database\": \"global-power-plants\",\r\n \"sql\": \"select country_long as value, count(*) as count from (\\n select rowid, country, country_long, name, gppd_idnr, capacity_mw, latitude, longitude, primary_fuel, other_fuel1, other_fuel2, other_fuel3, commissioning_year, owner, source, url, geolocation_source, wepp_id, year_of_capacity_data, generation_gwh_2013, generation_gwh_2014, generation_gwh_2015, generation_gwh_2016, generation_gwh_2017, generation_data_source, estimated_generation_gwh from [global-power-plants] \\n )\\n where country_long is not null\\n group by country_long order by count desc, value limit 4\",\r\n \"params\": []\r\n },\r\n {\r\n \"type\": \"sql\",\r\n \"start\": 31.221062485,\r\n \"end\": 31.228968364,\r\n \"duration_ms\": 7.905878999999061,\r\n \"traceback\": [\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/views/table.py\\\", line 760, in data\\n ) = await facet.facet_results()\\n\",\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/facets.py\\\", line 212, in facet_results\\n facet_rows_results = await self.ds.execute(\\n\",\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/app.py\\\", line 634, in execute\\n return await self.databases[db_name].execute(\\n\"\r\n ],\r\n \"database\": \"global-power-plants\",\r\n \"sql\": \"select owner as value, count(*) as count from (\\n select rowid, country, country_long, name, gppd_idnr, capacity_mw, latitude, longitude, primary_fuel, other_fuel1, other_fuel2, other_fuel3, commissioning_year, owner, source, url, geolocation_source, wepp_id, year_of_capacity_data, generation_gwh_2013, generation_gwh_2014, generation_gwh_2015, generation_gwh_2016, generation_gwh_2017, generation_data_source, estimated_generation_gwh from [global-power-plants] \\n )\\n where owner is not null\\n group by owner order by count desc, value limit 4\",\r\n \"params\": []\r\n },\r\n {\r\n \"type\": \"sql\",\r\n \"start\": 31.229809757,\r\n \"end\": 31.253902162,\r\n \"duration_ms\": 24.09240499999754,\r\n \"traceback\": [\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/views/table.py\\\", line 760, in data\\n ) = await facet.facet_results()\\n\",\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/facets.py\\\", line 212, in facet_results\\n facet_rows_results = await self.ds.execute(\\n\",\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/app.py\\\", line 634, in execute\\n return await self.databases[db_name].execute(\\n\"\r\n ],\r\n \"database\": \"global-power-plants\",\r\n \"sql\": \"select primary_fuel as value, count(*) as count from (\\n select rowid, country, country_long, name, gppd_idnr, capacity_mw, latitude, longitude, primary_fuel, other_fuel1, other_fuel2, other_fuel3, commissioning_year, owner, source, url, geolocation_source, wepp_id, year_of_capacity_data, generation_gwh_2013, generation_gwh_2014, generation_gwh_2015, generation_gwh_2016, generation_gwh_2017, generation_data_source, estimated_generation_gwh from [global-power-plants] \\n )\\n where primary_fuel is not null\\n group by primary_fuel order by count desc, value limit 4\",\r\n \"params\": []\r\n },\r\n {\r\n \"type\": \"sql\",\r\n \"start\": 31.255699745,\r\n \"end\": 31.256243889,\r\n \"duration_ms\": 0.544143999999136,\r\n \"traceback\": [\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/facets.py\\\", line 145, in suggest\\n row_count = await self.get_row_count()\\n\",\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/facets.py\\\", line 132, in get_row_count\\n await self.ds.execute(\\n\",\r\n \" File \\\"/usr/local/lib/python3.8/site-packages/datasette/app.py\\\", line 634, in execute\\n return await self.databases[db_name].execute(\\n\"\r\n ],\r\n \"database\": \"global-power-plants\",\r\n \"sql\": \"select count(*) from (select rowid, country, country_long, name, gppd_idnr, capacity_mw, latitude, longitude, primary_fuel, other_fuel1, other_fuel2, other_fuel3, commissioning_year, owner, source, url, geolocation_source, wepp_id, year_of_capacity_data, generation_gwh_2013, generation_gwh_2014, generation_gwh_2015, generation_gwh_2016, generation_gwh_2017, generation_data_source, estimated_generation_gwh from [global-power-plants] )\",\r\n \"params\": []\r\n }\r\n]\r\n```\r\n```\r\nfetch rows: 0.3869350000016425 ms\r\nfacet country_long: 4.875756000000564 ms\r\nfacet owner: 7.905878999999061 ms\r\nfacet primary_fuel: 24.09240499999754 ms\r\ncount: 0.544143999999136 ms\r\n```\r\nTotal = 37.8ms\r\n\r\nI modified the query to include the total count as well: https://global-power-plants.datasettes.com/global-power-plants?sql=with+cte+as+%28%0D%0A++select+rowid%2C+country%2C+country_long%2C+name%2C+owner%2C+primary_fuel%0D%0A++from+%5Bglobal-power-plants%5D%0D%0A%29%2C%0D%0Atruncated+as+%28%0D%0A++select+null+as+_facet%2C+null+as+facet_name%2C+null+as+facet_count%2C+rowid%2C+country%2C+country_long%2C+name%2C+owner%2C+primary_fuel%0D%0A++from+cte+order+by+rowid+limit+4%0D%0A%29%2C%0D%0Acountry_long_facet+as+%28%0D%0A++select+%27country_long%27+as+_facet%2C+country_long+as+facet_name%2C+count%28*%29+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A%29%2C%0D%0Aowner_facet+as+%28%0D%0A++select+%27owner%27+as+_facet%2C+owner+as+facet_name%2C+count%28*%29+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A%29%2C%0D%0Aprimary_fuel_facet+as+%28%0D%0A++select+%27primary_fuel%27+as+_facet%2C+primary_fuel+as+facet_name%2C+count%28*%29+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A%29%2C%0D%0Atotal_count+as+%28%0D%0A++select+%27COUNT%27+as+_facet%2C+%27%27+as+facet_name%2C+count%28*%29+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte%0D%0A%29%0D%0Aselect+*+from+truncated%0D%0Aunion+all+select+*+from+country_long_facet%0D%0Aunion+all+select+*+from+owner_facet%0D%0Aunion+all+select+*+from+primary_fuel_facet%0D%0Aunion+all+select+*+from+total_count&_trace=1\r\n\r\n```sql\r\nwith cte as (\r\n select rowid, country, country_long, name, owner, primary_fuel\r\n from [global-power-plants]\r\n),\r\ntruncated as (\r\n select null as _facet, null as facet_name, null as facet_count, rowid, country, country_long, name, owner, primary_fuel\r\n from cte order by rowid limit 4\r\n),\r\ncountry_long_facet as (\r\n select 'country_long' as _facet, country_long as facet_name, count(*) as facet_count,\r\n null, null, null, null, null, null\r\n from cte group by facet_name order by facet_count desc limit 3\r\n),\r\nowner_facet as (\r\n select 'owner' as _facet, owner as facet_name, count(*) as facet_count,\r\n null, null, null, null, null, null\r\n from cte group by facet_name order by facet_count desc limit 3\r\n),\r\nprimary_fuel_facet as (\r\n select 'primary_fuel' as _facet, primary_fuel as facet_name, count(*) as facet_count,\r\n null, null, null, null, null, null\r\n from cte group by facet_name order by facet_count desc limit 3\r\n),\r\ntotal_count as (\r\n select 'COUNT' as _facet, '' as facet_name, count(*) as facet_count,\r\n null, null, null, null, null, null\r\n from cte\r\n)\r\nselect * from truncated\r\nunion all select * from country_long_facet\r\nunion all select * from owner_facet\r\nunion all select * from primary_fuel_facet\r\nunion all select * from total_count\r\n```\r\nThe trace says that query took 34.801436999998714 ms.\r\n\r\nTo my huge surprise, this convoluted optimization only shaves the sum query time down from 37.8ms to 34.8ms!\r\n\r\nThat entire database file is just 11.1 MB though. Maybe it would make a meaningful difference on something larger?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970742415", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970742415, "node_id": "IC_kwDOBm6k_c453FqP", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T22:37:14Z", "updated_at": "2021-11-16T22:37:14Z", "author_association": "OWNER", "body": "The query takes 42.794ms to run.\r\n\r\nHere's the equivalent page using separate queries: https://global-power-plants.datasettes.com/global-power-plants/global-power-plants?_facet_size=3&_size=2&_nocount=1\r\n\r\nAnnoyingly I can't disable facet suggestions but keep facets.\r\n\r\nI'm going to turn on tracing so I can see how long the separate queries took.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1513#issuecomment-970738130", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1513", "id": 970738130, "node_id": "IC_kwDOBm6k_c453EnS", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-16T22:32:19Z", "updated_at": "2021-11-16T22:32:19Z", "author_association": "OWNER", "body": "I came up with the following query which seems to work!\r\n\r\n```sql\r\nwith cte as (\r\n select rowid, country, country_long, name, owner, primary_fuel\r\n from [global-power-plants]\r\n),\r\ntruncated as (\r\n select null as _facet, null as facet_name, null as facet_count, rowid, country, country_long, name, owner, primary_fuel\r\n from cte order by rowid limit 4\r\n),\r\ncountry_long_facet as (\r\n select 'country_long' as _facet, country_long as facet_name, count(*) as facet_count,\r\n null, null, null, null, null, null\r\n from cte group by facet_name order by facet_count desc limit 3\r\n),\r\nowner_facet as (\r\n select 'owner' as _facet, owner as facet_name, count(*) as facet_count,\r\n null, null, null, null, null, null\r\n from cte group by facet_name order by facet_count desc limit 3\r\n),\r\nprimary_fuel_facet as (\r\n select 'primary_fuel' as _facet, primary_fuel as facet_name, count(*) as facet_count,\r\n null, null, null, null, null, null\r\n from cte group by facet_name order by facet_count desc limit 3\r\n)\r\nselect * from truncated\r\nunion all select * from country_long_facet\r\nunion all select * from owner_facet\r\nunion all select * from primary_fuel_facet\r\n```\r\n(Limits should be 101, 31, 31, 31 but I reduced size to get a shorter example table).\r\n\r\nResults [look like this](https://global-power-plants.datasettes.com/global-power-plants?sql=with+cte+as+%28%0D%0A++select+rowid%2C+country%2C+country_long%2C+name%2C+owner%2C+primary_fuel%0D%0A++from+%5Bglobal-power-plants%5D%0D%0A%29%2C%0D%0Atruncated+as+%28%0D%0A++select+null+as+_facet%2C+null+as+facet_name%2C+null+as+facet_count%2C+rowid%2C+country%2C+country_long%2C+name%2C+owner%2C+primary_fuel%0D%0A++from+cte+order+by+rowid+limit+4%0D%0A%29%2C%0D%0Acountry_long_facet+as+%28%0D%0A++select+%27country_long%27+as+_facet%2C+country_long+as+facet_name%2C+count%28*%29+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A%29%2C%0D%0Aowner_facet+as+%28%0D%0A++select+%27owner%27+as+_facet%2C+owner+as+facet_name%2C+count%28*%29+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A%29%2C%0D%0Aprimary_fuel_facet+as+%28%0D%0A++select+%27primary_fuel%27+as+_facet%2C+primary_fuel+as+facet_name%2C+count%28*%29+as+facet_count%2C%0D%0A++null%2C+null%2C+null%2C+null%2C+null%2C+null%0D%0A++from+cte+group+by+facet_name+order+by+facet_count+desc+limit+3%0D%0A%29%0D%0Aselect+*+from+truncated%0D%0Aunion+all+select+*+from+country_long_facet%0D%0Aunion+all+select+*+from+owner_facet%0D%0Aunion+all+select+*+from+primary_fuel_facet):\r\n\r\n_facet | facet_name | facet_count | rowid | country | country_long | name | owner | primary_fuel\r\n-- | -- | -- | -- | -- | -- | -- | -- | --\r\n\u00a0 | \u00a0 | \u00a0 | 1 | AFG | Afghanistan | Kajaki Hydroelectric Power Plant Afghanistan | \u00a0 | Hydro\r\n\u00a0 | \u00a0 | \u00a0 | 2 | AFG | Afghanistan | Kandahar DOG | \u00a0 | Solar\r\n\u00a0 | \u00a0 | \u00a0 | 3 | AFG | Afghanistan | Kandahar JOL | \u00a0 | Solar\r\n\u00a0 | \u00a0 | \u00a0 | 4 | AFG | Afghanistan | Mahipar Hydroelectric Power Plant Afghanistan | \u00a0 | Hydro\r\ncountry_long | United States of America | 8688 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\ncountry_long | China | 4235 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\ncountry_long | United Kingdom | 2603 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nowner | \u00a0 | 14112 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nowner | Lightsource Renewable Energy | 120 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nowner | Cypress Creek Renewables | 109 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nprimary_fuel | Solar | 9662 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nprimary_fuel | Hydro | 7155 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\nprimary_fuel | Wind | 5188 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0 | \u00a0\r\n\r\nThis is a neat proof of concept. ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1055469073, "label": "Research: CTEs and union all to calculate facets AND query at the same time"}, "performed_via_github_app": null}