html_url,issue_url,id,node_id,user,created_at,updated_at,author_association,body,reactions,issue,performed_via_github_app
https://github.com/simonw/datasette/issues/1884#issuecomment-1321460293,https://api.github.com/repos/simonw/datasette/issues/1884,1321460293,IC_kwDOBm6k_c5Ow-JF,15178711,2022-11-21T04:40:55Z,2022-11-21T04:40:55Z,CONTRIBUTOR,"Counting any virtual tables can be pretty tricky. On one hand, counting a [CSV virtual table](https://www.sqlite.org/csv.html) would return the number of rows in the CSV, which is helpful (but can be I/O intensive). Counting a [FTS5 virtual table](https://www.sqlite.org/fts5.html) would return the number of entries in the FTS index, which is kindof helpful, but can be misleading in some cases.
On the other hand, arbitrarily running `COUNT(*)` on some virtual tables can be incredibly expensive. SQLite offers new shortcuts/pushdowns on `COUNT(*)` queries for virtual tables, and instead calls the underlying vtab implementation and iterates through all rows in the table without discretion. For example, a virtual table that's backed by a Postgres table would call `select * from pg_table`, which would use up a lot of network and CPU calls. Or a virtual table backed by a [google sheet](https://github.com/0x6b/libgsqlite) would make network/API requests to get all the rows from the sheet just to make a count.
The [`pragma_table_list`](https://www.sqlite.org/pragma.html#pragma_table_list) pragma tells you when a table is a regular table or virtual (in the `type` column), but was only added in version 3.37.0 (2021-11-27).
Personally, I wouldnt try to `COUNT(*)` virtual tables - it depends on how the virtual table is implemented, it requires that the connection has the proper extensions loaded, and it may accientally cause perf issues for new-age extensions. A few extensions that I'm writing have virtual tables that wouldn't benefit much from `COUNT(*)`, and the fact that SQLite iterates through all rows in a table to count just makes things worse. ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1439009231,
https://github.com/simonw/datasette/issues/1884#issuecomment-1314066229,https://api.github.com/repos/simonw/datasette/issues/1884,1314066229,IC_kwDOBm6k_c5OUw81,25778,2022-11-14T16:48:35Z,2022-11-14T16:48:35Z,CONTRIBUTOR,"I'm realizing I don't know if a virtual table will ever return a count. Maybe it depends on the implementation. For these three, just checking now, it'll always return zero.
That said, I'm not sure there's any downside to having them return zero and caching that. (They're hidden, too.) ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1439009231,
https://github.com/simonw/datasette/issues/1884#issuecomment-1314054300,https://api.github.com/repos/simonw/datasette/issues/1884,1314054300,IC_kwDOBm6k_c5OUuCc,9599,2022-11-14T16:40:06Z,2022-11-14T16:40:06Z,OWNER,"I wonder if there are any reasons that inspect SHOULD try to count virtual tables? Like are there any likely uses for a cirial table where the count is both interesting and likely to be accessed often enough that it's worth caching?
I have an issue open to add a setting to disable table counts entirely:
- #1818
Maybe that should be expanded to automatically disable row counts for virtual tables entirely? Which would mean no count would be shown for them in the UI.
If you desperately wanted a count you would then have to run a count(*) query against them explicitly.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1439009231,
https://github.com/simonw/datasette/issues/1884#issuecomment-1313962183,https://api.github.com/repos/simonw/datasette/issues/1884,1313962183,IC_kwDOBm6k_c5OUXjH,25778,2022-11-14T15:46:32Z,2022-11-14T15:46:32Z,CONTRIBUTOR,"It does work, though I think it's probably still worth excluding virtual tables that will always be zero. Here's the same inspection as before, now with `--load-extension spatialite`:
```json
{
""alltheplaces"": {
""hash"": ""0843cfe414439ab903c22d1121b7ddbc643418c35c7f0edbcec82ef1452411df"",
""size"": 963375104,
""file"": ""alltheplaces.db"",
""tables"": {
""spatial_ref_sys"": {
""count"": 6215
},
""spatialite_history"": {
""count"": 18
},
""sqlite_sequence"": {
""count"": 2
},
""geometry_columns"": {
""count"": 3
},
""spatial_ref_sys_aux"": {
""count"": 6164
},
""views_geometry_columns"": {
""count"": 0
},
""virts_geometry_columns"": {
""count"": 0
},
""geometry_columns_statistics"": {
""count"": 3
},
""views_geometry_columns_statistics"": {
""count"": 0
},
""virts_geometry_columns_statistics"": {
""count"": 0
},
""geometry_columns_field_infos"": {
""count"": 0
},
""views_geometry_columns_field_infos"": {
""count"": 0
},
""virts_geometry_columns_field_infos"": {
""count"": 0
},
""geometry_columns_time"": {
""count"": 3
},
""geometry_columns_auth"": {
""count"": 3
},
""views_geometry_columns_auth"": {
""count"": 0
},
""virts_geometry_columns_auth"": {
""count"": 0
},
""data_licenses"": {
""count"": 10
},
""sql_statements_log"": {
""count"": 0
},
""states"": {
""count"": 56
},
""counties"": {
""count"": 3234
},
""idx_states_geometry_rowid"": {
""count"": 56
},
""idx_states_geometry_node"": {
""count"": 3
},
""idx_states_geometry_parent"": {
""count"": 2
},
""idx_counties_geometry_rowid"": {
""count"": 3234
},
""idx_counties_geometry_node"": {
""count"": 98
},
""idx_counties_geometry_parent"": {
""count"": 97
},
""idx_places_geometry_rowid"": {
""count"": 1236796
},
""idx_places_geometry_node"": {
""count"": 38163
},
""idx_places_geometry_parent"": {
""count"": 38162
},
""places"": {
""count"": 1332609
},
""SpatialIndex"": {
""count"": 0
},
""ElementaryGeometries"": {
""count"": 0
},
""KNN"": {
""count"": 0
},
""idx_states_geometry"": {
""count"": 56
},
""idx_counties_geometry"": {
""count"": 3234
},
""idx_places_geometry"": {
""count"": 1236796
}
}
}
}
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1439009231,
https://github.com/simonw/datasette/issues/1884#issuecomment-1311269045,https://api.github.com/repos/simonw/datasette/issues/1884,1311269045,IC_kwDOBm6k_c5OKGC1,9599,2022-11-11T06:08:28Z,2022-11-11T06:08:28Z,OWNER,Does that work if you add `--load-extension spatialite`?,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1439009231,
https://github.com/simonw/datasette/issues/1884#issuecomment-1309735529,https://api.github.com/repos/simonw/datasette/issues/1884,1309735529,IC_kwDOBm6k_c5OEPpp,25778,2022-11-10T03:57:23Z,2022-11-10T03:57:23Z,CONTRIBUTOR,Here's how to get a list of virtual tables: https://stackoverflow.com/questions/46617118/how-to-fetch-names-of-virtual-tables,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1439009231,