Skip to content

Rel8 Performance x100 Slower than SQL #290

@idontgetoutmuch

Description

@idontgetoutmuch

I am using https://hackage.haskell.org/package/rel8-1.4.1.0 and have the following query in Haskell. Sadly it takes 180 seconds to run.

sumTest = do
  widgetsPerDay <- each productionWidget
  daysPerMonth <- each daysInMonth
  where_ $ cYear widgetsPerDay ==. Rel8.nullify (getYear daysPerMonth) &&.
           cMonth widgetsPerDay ==. Rel8.nullify (getMonth daysPerMonth)
  let pp = Rel8.groupBy (pPeriod widgetsPerDay)
      t  = Rel8.sum (pWidget widgetsPerDay * (Rel8.fromIntegral daysPerMonth.dDaysInMonth))
  return (pp, t)

When I code up the SQL by hand it takes 3 seconds.

SELECT
    wp.c_year AS production_year,
    wp.c_month AS production_month,
    SUM(wp.p_widgets * dp.d_days_in_month) AS total_widgets_produced
FROM
    production_widget wp
JOIN
    ref_days_in_month dp ON
        CAST(wp.c_year AS INTEGER) = EXTRACT(YEAR FROM dp.d_date) AND
        CAST(wp.c_month AS INTEGER) = EXTRACT(MONTH FROM dp.d_date)
GROUP BY
    wp.c_year, wp.c_month;

Here is what showQuery gives me:

"SELECT"
"CAST(\"result0_6\" AS text) as \"_1\","
"CAST(CAST(\"result1_6\" AS numeric) AS numeric) as \"_2\","
"CAST(CAST(\"result2_6\" AS numeric) AS numeric) as \"_3\""
"FROM (SELECT"
"      \"inner0_6\" as \"result0_6\","
"      SUM(\"inner1_6\") as \"result1_6\","
"      SUM(\"inner2_6\") as \"result2_6\""
"      FROM (SELECT"
"            \"p_period14_1\" as \"inner0_6\","
"            \"p_widgets62_1\" as \"inner1_6\","
"            (\"p_widgets62_1\") * (CAST(\"d_days_in_month1_3\" AS numeric)) as \"inner2_6\","
"            *"
"            FROM (SELECT"
"                  *"
"                  FROM (SELECT"
"                        \"c_months_since_start\" as \"c_months_since_start0_1\","
"                        \"d_days_in_month\" as \"d_days_in_month1_1\","
"                        \"c_quarter\" as \"c_quarter2_1\","
"                        \"c_year\" as \"c_year3_1\","
"                        \"c_month\" as \"c_month4_1\","
"                        ...
"                        \"p_widgets\" as \"p_widgets62_1\","
"                        FROM \"production_widget\" as \"T1\") as \"T1\","
"                       LATERAL"
"                       (SELECT"
"                        \"d_date\" as \"d_date0_3\","
"                        \"d_days_in_month\" as \"d_days_in_month1_3\""
"                        FROM \"ref_days_in_month\" as \"T1\") as \"T2\""
"                  WHERE (((((\"c_year3_1\") IS NULL) AND ((CAST(trunc(CAST(EXTRACT(YEAR FROM(CAST(\"d_date0_3\" AS timestamptz))) AS float8)) AS int2)) IS NULL)) OR (((\"c_year3_1\") = (CAST(trunc(CAST(EXTRACT(YEAR FROM(CAST(\"d_date0_3\" AS timestamptz))) AS float8)) AS int2))) AND (COALESCE((\"c_year3_1\") = (CAST(trunc(CAST(EXTRACT(YEAR FROM(CAST(\"d_date0_3\" AS timestamptz))) AS float8)) AS int2)),FALSE)))) AND ((((\"c_month4_1\") IS NULL) AND ((CAST(trunc(CAST(EXTRACT(MONTH FROM(CAST(\"d_date0_3\" AS timestamptz))) AS float8)) AS int2)) IS NULL)) OR (((\"c_month4_1\") = (CAST(trunc(CAST(EXTRACT(MONTH FROM(CAST(\"d_date0_3\" AS timestamptz))) AS float8)) AS int2))) AND (COALESCE((\"c_month4_1\") = (CAST(trunc(CAST(EXTRACT(MONTH FROM(CAST(\"d_date0_3\" AS timestamptz))) AS float8)) AS int2)),FALSE)))))) as \"T1\") as \"T1\""
"      GROUP BY \"inner0_6\") as \"T1\""

It looks very slow because there’s a query inside a query inside another query: 5 sub queries? But I am an SQL noob. Maybe I mis-formulated the Haskell?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions