fireproofsocks

fireproofsocks

Optimization by storing database table in memory?

I’m hoping for some advice in optimizing a Phoenix/Elixir application with respect to a couple different kinds of database tables. The regular CRUD stuff is simple: lookups based on an id that can get cached at the database layer or in Elixir (e.g. using Cachex) as needed. Those use-cases are under control. There are 2 other use cases that are a bit trickier.

First use case: small, commonly used tables like “countries” or “currencies”. Our application has dozens of small (ish) tables with maybe 100 rows each whose values do not change often. Is it possible in Elixir to load these tables into memory or cache when the application is started? We could save ourselves many database lookups and still maintain a modest memory footprint. Are there recommended approaches to this tactic? Has anyone seen a tutorial for this?

Second use case: large, but critical tables that do not change often. This one is trickier, and I may not be able to describe the exact need this fills without ending up in the weeds. But for every request into the application, we need to do a couple lookups to this table to “translate” certain values that relate to the route and do some “reverse lookups” of other values. Currently, in our legacy PHP application, these values are stored in Redis, and that works reasonably well. The one feature of Redis that makes this approach possible is its mget feature: with a single Redis call, we can retrieve multiple records. If this were happening in a SQL database, it might be analogous to a query like “SELECT value FROM table WHERE column IN (a, b, c, …)” where we specify ~50 values to lookup.

This 2nd use case is trickier because of the “mget” lookup – I’m not sure how we might cache that because the result returned depends on a fairly long set of conditions.

To clarify the difficulties, we have not been successful in any solution that attempted to “lazy load” results: the query simply takes a bit too long and the results are unique enough so that there isn’t much payoff afterwards because the results are rarely re-used. So in this case, we have needed to preload the results in Redis, and this has worked reasonably well.

If anyone has some advice / links / thoughts on the matter, I’m thankful for any guidance!

Most Liked

michalmuskala

michalmuskala

If the key is part of a match spec, it doesn’t. In ordered_set tables just a prefix of a key is enough not to trigger a full table scan.

chvanikoff

chvanikoff

it depends on how complex it is. ETS doesn’t provide SQL-like queries, however it is much more powerful than just a simple key lookup. Search for :ets.match/2 match patterns, or look through original (Erlang) ETS docs here: ets — OTP 29.0.2 (stdlib 8.0.1)

OvermindDL1

OvermindDL1

This performs a linear search internally though.

But yeah, overall ETS (or a wrapper like Cachex, my favorite thus far) is exactly suited to be a cache, just listen for postgres notifications to know when to invalidate and/or update values. With Cachex you can also limit the number of entries (to keep memory from blowing), auto reclaim unused values, etc…

Where Next?

Popular in Questions Top

vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New

Other popular topics Top

JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54092 488
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42576 114
New

We're in Beta

About us Mission Statement