GORM Playground Link

https://github.com/go-gorm/playground/pull/722

Version

Superior to v1.25.6

Description

This issues to demonstrate an issue in GORM's query behavior.

The function illustrates potential inefficiencies and unexpected results that may have been introduced due to a previous fix in GORM's preloading and join operations.

Background

Previously, a fix was implemented in GORM to address an issue where, when joining on Account.Pet and then preloading Account.Companies, the account was loaded twice, even though it was already present in the main query. This fix aimed to improve the consistency and efficiency of the query process.

Current Issue

However, the provided playground suggests that the fix may have unintentionally introduced another issue. The test highlights the following:

Unexpected Queries: The function is expected to execute two queries (one for fetching user data and another for related data). Instead, there may be an additional, unnecessary query, suggesting an n+1 query problem.

TLDR:

DB.Joins("Company").Preload("Company.Addresses").Find(&result).Error

is resulting in

2024/04/23 15:08:19 /Users/alexisviscogliosi/dev/go-playground/db.go:59
[1.205ms] [rows:2] SELECT * FROM "addresses" WHERE "addresses"."company_id" = 1

2024/04/23 15:08:19 /Users/alexisviscogliosi/dev/go-playground/db.go:59
[0.634ms] [rows:2] SELECT * FROM "addresses" WHERE "addresses"."company_id" = 2

2024/04/23 15:08:19 /Users/alexisviscogliosi/dev/go-playground/db.go:59
[3.667ms] [rows:2] SELECT "users"."id","users"."created_at","users"."updated_at","users"."deleted_at","users"."name","Company"."id" AS "Company__id","Company"."name" AS "Company__name","Company"."user_id" AS "Company__user_id" FROM "users" LEFT JOIN "companies" "Company" ON "users"."id" = "Company"."user_id

Note: if there is more than 2 companies it results in N queries where N is the number of companies.

Instead of

SELECT `users`.`id`,`users`.`created_at`,`users`.`updated_at`,`users`.`deleted_at`,`users`.`name`,`Company`.`id` AS `Company__id`,`Company`.`name` AS `Company__name`,`Company`.`user_id` AS `Company__user_id` FROM `users
        LEFT JOIN `companies` `Company` ON `users`.`id` = `Company`.`user_id`
        WHERE `users`.`deleted_at` IS NULL
SELECT * FROM `companies` WHERE `companies`.`id` IN (1, 2)

In version v1.25.6 the select of addresses where using a IN clause but have the problem of doing a second query with companies (https://github.com/go-gorm/gorm/issues/6715#issuecomment-1832455676)