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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions