sheepduke

sheepduke

Mnesia 100x slower to query compared with SQLite?

Hi folks,

I just started to explore the Mnesia database. I read many docs, posts and resources provided by Elixir forum, but still could not found a solution:

My Mnesia is 100x times slower to query (scan) compared with Ecto/SQLite3.

Initialization

The following code shows how Mnesia was initialized:

defmodule Data.Test do
  use Memento.Table,
    attributes: [
      :uuid,
      :name
    ],
    index: [:name]
end

Memento.stop()
Memento.Schema.create([node()])
Memento.start()

Memento.Table.create!(Data.Test, disc_copies: nodes)

Memento.transaction!(fn ->
  Enum.each(1..100_000, fn i ->
    Memento.Query.write(%Data.Test{
      uuid: Ecto.UUID.generate(),
      name: "Test #{i}"
    })
  end)
end)

Then I created an exactly same table in SQLite3, without index.

Query

The following code shows the query process:

:timer.tc(fn ->
  Memento.transaction!(fn ->
    Memento.Query.all(Data.Test)
    |> Stream.filter(&String.contains?(&1.name, "12345"))
    |> Enum.to_list()
  end)
end)

Test.Repo.query("select * from test where name like '%12345%'")

The result was about 1600 ms and 16 ms respectively.

I replaced the Stream in Mnesia query with :mnesia.foldl (without Memento) and the result was almost identical (1400 ms maybe, still ~100x times).

Question

My understanding is that SQL like '%xxx%' leads to a full table scan, which is same as Mnesia.

Since Mnesia stores the data in memory, why is the table scan so slow? Am I miss anything?

Any clue is sincerely appreciated!

Marked As Solved

Rustixir

Rustixir

Hi , I working with mnesia for distributed read-heavy data application for three last year.

Mnesia is a distributed, concurrency DBMS but Sqlite is a embedded database.

for real-project if you need high concurrency access to Database with Sqlite become bottleneck .

  1. Mnesia intenal use ETS for disc_copies and ram_copies
    and that have many parameter for tune maximize performance

  2. if you want for a single node/machine and maximize performance use ETS

  3. if you want use mnesia use itself module → :mnesia

  4. for increase performance for read/query use :mnesia.activity with <:async_dirty > parameter

  5. if you want use mnesia with maximize performance for read/query use
    :mnesia.activity with < :ets > parameter

Also Liked

cmkarlsson

cmkarlsson

mnesia and ets are key/value database. It is best used when you have a specific value to retrieve.

That said, if you can structure your object in a way that :mnesia.select can be used then it is much faster. Mnesia select relies on match specifications (Match Specifications in Erlang — OTP 29.0.2 (erts 17.0.2)) which are a bit gnarly to get your head around but very useful, not only in mnesia but also in ets and if you are doing tracing.

Match specifications do not support matching on parts of binary strings so your specific example would not work as is, but they are a faster way to get information out of mnesia and ets compared to foldl or iterating the table.

I see that Memento also support select (a simplified version of erlang’s matchspecs) and select_raw with the full power of select. Perhaps it is worth investigating.

Exadra37

Exadra37

The queries are not comparable at all.

In SQLITe everything its done by the database engine, but in the Mnesia query you are splitting the work between Mnesia and Elixir.

You can read the Memento Docs to see how you can properly do your SQLITe query only with Memento or you can read the Mnesia docs:

bit4bit

bit4bit

hi, try mnesia directly maybe get a better answer

Where Next?

Popular in Questions Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
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
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
vac
Hi, I’m quite new in Elixir and I’m trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and I...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New

Other popular topics Top

AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43622 214
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
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
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39297 209
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New

We're in Beta

About us Mission Statement