Reinitializing the topic: same problem with Postgres/Ecto.
create table(:merchant_transactions) do
add :merchant_id, :integer
add :transaction_id, :integer
add :usd_amount, :decimal
add :trans_amount, :decimal
add :trans_currency_code, :string
add :trans_date, :naive_datetime
add :trans_created_at, :naive_datetime
add :trans_updated_at, :naive_datetime
timestamps()
end
create index("merchant_transactions", [:merchant_id])
create index("merchant_transactions", [:inserted_at])
create index("merchant_transactions", [:trans_date])
Model:
schema "merchant_transactions" do
field :merchant_id, :integer
field :transaction_id, :integer
field :usd_amount, :decimal
field :trans_amount, :decimal
field :trans_currency_code, :string
field :trans_date, Timex.Ecto.DateTime
field :trans_created_at, Timex.Ecto.DateTime
field :trans_updated_at, Timex.Ecto.DateTime
timestamps([autogenerate: {Timex, :now, []}])
end
def transactions_after_date(date) do
from m in MerchantTransaction,
where: m.trans_date > ^date
end
Query:
options = %{time_term: "months", time_value: -1, grouping: "sum"}
now = Timex.now
hour_ago = Timex.shift(now, [{String.to_atom(options.time_term), options.time_value}])
{:ok, str_hour_ago} = Timex.format(hour_ago, "{ISO:Extended:Z}")
transactions = MerchantTransaction.transactions_after_date(str_hour_ago) |> Markers.Repo.all
When called in iex
the last line is executed in 300-500ms:
:timer.tc(fn -> transactions = MerchantTransaction.transactions_after_date(str_hour_ago) |> Markers.Repo.all end) |> elem(0)
[debug] QUERY OK source="merchant_transactions" db=453.7ms decode=172.6ms
SELECT m0."id", m0."merchant_id", m0."transaction_id", m0."usd_amount", m0."trans_amount", m0."trans_currency_code", m0."trans_date", m0."trans_created_at", m0."trans_updated_at", m0."inserted_at", m0."updated_at" FROM "merchant_transactions" AS m0 WHERE (m0."trans_date" > $1) [{{2018, 2, 20}, {10, 36, 0, 624233}}]
630562
iex(28)> :timer.tc(fn -> transactions = MerchantTransaction.transactions_after_date(str_hour_ago) |> Markers.Repo.all end) |> elem(0)
[debug] QUERY OK source="merchant_transactions" db=403.6ms decode=145.7ms
SELECT m0."id", m0."merchant_id", m0."transaction_id", m0."usd_amount", m0."trans_amount", m0."trans_currency_code", m0."trans_date", m0."trans_created_at", m0."trans_updated_at", m0."inserted_at", m0."updated_at" FROM "merchant_transactions" AS m0 WHERE (m0."trans_date" > $1) [{{2018, 2, 20}, {10, 36, 0, 624233}}]
552560
iex(29)> :timer.tc(fn -> transactions = MerchantTransaction.transactions_after_date(str_hour_ago) |> Markers.Repo.all end) |> elem(0)
[debug] QUERY OK source="merchant_transactions" db=245.1ms decode=127.9ms
SELECT m0."id", m0."merchant_id", m0."transaction_id", m0."usd_amount", m0."trans_amount", m0."trans_currency_code", m0."trans_date", m0."trans_created_at", m0."trans_updated_at", m0."inserted_at", m0."updated_at" FROM "merchant_transactions" AS m0 WHERE (m0."trans_date" > $1) [{{2018, 2, 20}, {10, 36, 0, 624233}}]
375806
iex(30)> :timer.tc(fn -> transactions = MerchantTransaction.transactions_after_date(str_hour_ago) |> Markers.Repo.all end) |> elem(0)
[debug] QUERY OK source="merchant_transactions" db=228.7ms decode=292.4ms
SELECT m0."id", m0."merchant_id", m0."transaction_id", m0."usd_amount", m0."trans_amount", m0."trans_currency_code", m0."trans_date", m0."trans_created_at", m0."trans_updated_at", m0."inserted_at", m0."updated_at" FROM "merchant_transactions" AS m0 WHERE (m0."trans_date" > $1) [{{2018, 2, 20}, {10, 36, 0, 624233}}]
526772
Direct call in psql
is very fast:
explain analyze SELECT m0."id", m0."merchant_id", m0."transaction_id", m0."usd_amount", m0."trans_amount", m0."trans_currency_code", m0."trans_date", m0."trans_created_at", m0."trans_updated_at", m0."inserted_at", m0."updated_at" FROM "merchant_transactions" AS m0 WHERE (m0."trans_date" > '2018-02-20 10:36:00.624233');
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------
Seq Scan on merchant_transactions m0 (cost=0.00..491.24 rows=17379 width=610) (actual time=0.009..4.742 rows=17379 loops=1)
Filter: (trans_date > '2018-02-20 10:36:00.624233'::timestamp without time zone)
Planning time: 0.150 ms
Execution time: 6.082 ms
(4 rows)
Even if I call the query directly like
SELECT m0."id", m0."merchant_id", m0."transaction_id", m0."usd_amount", m0."trans_amount", m0."trans_currency_code", m0."trans_date", m0."trans_created_at", m0."trans_updated_at", m0."inserted_at", m0."updated_at" FROM "merchant_transactions" AS m0 WHERE (m0."trans_date" > '2018-02-20 10:36:00.624233');
the resulting out put is shown very fast. I understand that it’s not taking full set at once, and no elixir decoding, but still: why is that SO long? half a second!
Resulting data set is 17379 rows, is that a problem?
Postgres and Iex are running on same machine locally, without docker.
Tried config with localhost
and 127.0.0.1
- same result.
Any clues?
Thanks!