jordpo

jordpo

Handling a very large database query using streams

Hi!

We are trying to optimize the query and data handling for a very large database query (up to 10s of millions of rows). We are using streams both at the adapter level and Stream methods.

Here is our usage

    Repo.transaction(fn ->
      Filter.construct_where_clause(filters)
      |> Sql.stream()
      |> Stream.map(&(transform_rows(&1)))
      |> Stream.transform(
        fn -> Handle.start() end,
        fn chunk, acc -> Handle.iterate_chunk(chunk, acc) end,
        fn acc -> Handle.end_all() end)
      |> Stream.run
    end, timeout: :infinity)

Where Sql.stream() does

Ecto.Adapters.SQL.stream(Repo, sql, [], max_rows: 1_000)

We’re noticing that the reducer in the Stream.transform can take a really long time (we are up to 40s) to do the initial chunk. Subsequent chunks are really fast. The start function in Stream.transform happens really fast as well, it just hangs at the reducer.

Are we missing something here? The max_rows that we are loading is only 1,000 so we think it would be fast. It seems like the data is getting fully loaded before chunking in the Stream.transform reducer.

Thank you!

Marked As Solved

Rik

Rik

Regardless of the elixir coding constructs, a database like Oracle or Postgres receives a query and will start retrieving rows. But when the query must perform a full table scan, it can take some time. Or it has an order-by clause, it will not return before it has completed the job for 100%. The database is the bottleneck, streams are doing nothing when the database is busy.

Also Liked

al2o3cr

al2o3cr

Ecto.Adapters.SQL.stream is using a cursor under the hood; this sounds like a consequence of that.

Last Post!

jordpo

jordpo

Thanks. Yeah this clarified a lot. I wasn’t looking necessarily for a solution here but just an explanation as to what the bottleneck is.

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
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
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

Other popular topics Top

jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31586 112
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
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
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

We're in Beta

About us Mission Statement