Best way to get multiple keys from static ETS table

Background

I have an ets table that has, for each key, a list of items. ETS tables have O(1) complexity when using :ets.lookup, as we all know and they are super fast, but for my specific use case, I need to ask to the ets table for more than 1 key at a time.

This means I have 2 options:

  1. Perform multiple lookups
  2. Perform a match or select on the keys

Multiple lookups

I don’t really like this approach because it would mean my operation is not atomic. This is a big no no.

Match or Select on keys

This is my preferred approach since I want the operation to be as efficient as possible. I am also not going to look for patterns in keys, I am simply going to look directly for keys that match my spec, so it should be fast.

I do have several questions about match and select though (see Questions section)

Issue

The problem here is that I don’t know how to use :ets.match or it’s select variant correctly. This is an example:

iex(27)> table = :ets.new(:table, [:public])
#Reference<0.830523521.2311716867.20185>
iex(28)> :ets.insert(table, {:a, [{:banana, :orange, 10}, {:tomato, :potato, 6}]})
true
iex(29)> :ets.insert(table, {:b, [{:car, :moto, 1}, {:plane, :heli, 60}]})        
true
iex(30)> :ets.tab2list(table) 
[
  b: [{:car, :moto, 1}, {:plane, :heli, 60}],
  a: [{:banana, :orange, 10}, {:tomato, :potato, 6}]
]
ex(32)> :ets.match(table, [:a, :b]) # I want to get the values from both keys :a :b
[]

Questions

  1. What am I doing wrong?
  2. How do I optimize my match queries so they are atomic? From the docs:

Traversals using match and select functions may not need to scan the entire table depending on how the key is specified. A match pattern with a fully bound key (without any match variables) will optimize the operation to a single key lookup without any table traversal at all.

  1. The data on my table will never change. Does it matter if I make the table an ordered_set or are the gains for match and select not worth it?