Typical ways to start beam end up doing a lot of work you might not need.
Taking some time to fiddle with the startup settings for a short running task can make a big difference. You might actually get better results by setting it to single cpu, because there's less setup that way. Really depends on how much total cpu time your work takes. If your VM is going to run for a year (or more), startup time hardly matters and so the defaults aren't highly tuned for a 30 second script.
The real gain here would probably be streaming chunks of rows out of ecto and maybe firing those off to tasks per CPU core. Which is easier than it sounds.
That said, you had working code so no real reason to rewrite it except as a learning exercise.