Skip to content

has[Association]() makes a complete INNER JOIN SELECT - should be lightweight confirmation, proof and solution #10514

@the-vampiire

Description

@the-vampiire

What are you doing?

Using the has[Association]() method on a Model instance

...Model defs...

ModelA.belongsToMany(models.ModelB, { through: ModelC });
ModelB.belongsToMany(models.ModelA, { through: ModelC });

...create entries...

instanceA.hasB(instanceB);

What do you expect to happen?

When a has[Association]() method is called that a lightweight (0 attributes) SELECT is made to confirm the association without wasting resources.

What is actually happening?

Calling has[Association]() makes a heavy INNER JOIN SELECT query.

  • selects all attributes from the associated table and the join table
  • none of the selected attributes are returned / used
  • since the method returns a boolean true or false (confirmation method) this big SELECT is pointless

calling instanceA.hasB(instanceB) results in the following SQL echo:

Executing (default): SELECT "ModelB"."id", "ModelB"."email", "ModelB"."first_name", "ModelB"."last_name", "ModelB"."company", "ModelB"."created_at", "ModelB"."updated_at", "ModelC"."id" AS "ModelC.id", "ModelC"."paid" AS "ModelC.paid", "ModelC"."created_at" AS "ModelC.created_at", "ModelC"."updated_at" AS "ModelC.updated_at", "ModelC"."a_id" AS "ModelC.a_id", "ModelC"."b_id" AS "ModelC.b_id" FROM "bs" AS "ModelB" INNER JOIN "cs" AS "ModelC" ON "ModelB"."id" = "ModelC"."b_id" AND "ModelC"."a_id" = 50 WHERE ((("ModelB"."id" = 97)));

Temporary Solution

correct boolean result returned when modifying call as

  • instanceA.hasB(instanceB, { attributes: [], joinTableAttributes: [] });
  • now makes a lightweight SELECT:
Executing (default): SELECT  FROM "bs" AS "ModelB" INNER JOIN "cs" AS "ModelC" ON "ModelB"."id" = "ModelC"."b_id" AND "ModelC"."a_id" = 50 WHERE ((("ModelB"."id" = 97)));

Suggestion

Change internal behavior of has[Association]() method calls to use options object { attributes: [], joinTableAttributes: [] } so that this operation does not perform such a heavy query.

Output, either JSON or SQL

Dialect: postgres (but I believe any should be affected)
Dialect version: 9.6.10
Database version: 9.6.10
Sequelize version: 4.43.0
Tested with latest release: No (If yes, specify that version)

Note : Your issue may be ignored OR closed by maintainers if it's not tested against latest version OR does not follow issue template.

Metadata

Metadata

Assignees

No one assigned

    Labels

    performanceFor issues and PRs. Things that affect the performance of Sequelize.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions