Conversation
|
View Vercel preview at instant-www-js-vae-uuids-jsv.vercel.app. |
| (assoc acc pat-idx {:sym sym | ||
| :ref-value? (and (= :v component) | ||
| (= :eav (idx-key (:idx named-p))))}) | ||
| (= :vae (idx-key (:idx named-p))))}) |
There was a problem hiding this comment.
This also fixes a bug in the topics, where we weren't removing vae triples from the topics symbol map. (see https://github.com/jsventures/instant/pull/827 for more explanation).
I don't think we actually encounter the bug in prod because we always invalidate the id field on updates (will be fixed by #739). What could happen when we fix the id bug: say you have a query that orders on order-field, if you update order-field on an existing entity outside of the result set so that it should be in the result set, we won't invalidate the query because our topic is looking at a specific entity (e.g. [:eid :order-field _]). With this change, the topic will be [_ :order-field :_], so the query will get invalidated. Again, it's not a problem now because we have the topic [_ :id _] and it gets invalidated on any change.
| end; | ||
| $$; | ||
|
|
||
| -- Create this index concurrently before running the migration |
| patterns)] | ||
| (collect-query-results ctx (:data datalog-result) forms))))) | ||
|
|
||
| (defn explain |
stopachka
left a comment
There was a problem hiding this comment.
Genius find @dwwoelfel!
We only put refs in the vae and eav indexes so we know that the value will be a uuid. This PR stores those uuids as actual uuids in the index itself.
This makes the indexes take up less space (they're about 30% smaller).
The big change is that now we can use
vaeinstead ofeavwhen we do a join on a ref, which saves us doing an expensive json->uuid conversion in the join filter. Here's a simple example:{:books {:where {:category "western" :author :eid/elmer-kelton}}}That generates two ctes:
If we use the
eavindex for m_1, thevis at the end of the index. Postgres does a nested loop and filters the join onentity_id = json_to_uuid(value). It looks something like this:If we use the
vaeindex for m_1, then thevis at the start of the index and postgres will use that in the index cond instead of the less efficient join filter. It looks something like this:((value ->> 0))::uuidis already in the index, so we never have to do any json->uuid conversion at all in the query itself. We avoid the expensive join filter, which in my backtesting makes queries much faster.We also don't have to carry around the
match_x_x_value_uuidany more. Instead ofvalue_uuid, we trackis_ref_valueso that we know to convert it from a string to a uuid insql-row->triple.Results from the backtest:
I'm not super concerned about the first two queries that got worse because they're not slower if I enable pg hints.
Deployment plan