SQLite Forum

Clustering tables on an expression index
Login
A table's rows are ordered either in rowid-order (or in PK-order for  
without-rowid tables), there's nothing you can do about that. Modulo  
page-fragmentation of course, which you get rid of with vacuum.

So either you do your inserts in geohash-order, when you don't want to  
control the rowid, or you alias the rowid with an INTEGER PRIMARY KEY  
column, which is derived from your geohash **and** is UNIQUE of course...  
That's not too different from your without-rowid analysis, which is correct to me.

If you don't care about controlling the rowid, you can also do a [CTAS][CTAS]  
to *re-order* your table into another one, and replace (delete+rename) the  
old one. Because CTAS's doc says:

> Rows are assigned contiguously ascending rowid values, starting with 1,  
> in the order that they are returned by the SELECT statement

Thus if the CTAS's right-hand-side SELECT is ordered by GeoHash, so will  
the table be as well. That's basically equivalent to a _custom vacuum_  
for that table, kinda...  But in all cases, that geohash ordering  
(i.e. clustering) won't be maintained against further DMLs, which might  
be OK if you're *read-mostly*.

I guess you could also create an non-unique covering index, with the geohash  
as the first column, which would act as a kind of _shadow table_, with enough  
columns in it that most queries don't need to go back to the _main_ table.  
You gain automatic maintenance of that index, in geohash order, but at the cost  
of duplicating your table...

[CTAS]: https://www.sqlite.org/lang_createtable.html#createtabas