go-gorm / playground

GORM Playground (Please Create PR for this project to report issues)
MIT License
89 stars 681 forks source link

queries: n+1 queries #722

Open alexisvisco opened 5 months ago

alexisvisco commented 5 months ago

Description

This pull request aims to demonstrate an issue in GORM's query behavior as observed in the provided test function TestGORM. 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 test function suggests that the fix may have unintentionally introduced another issue. The test highlights the following:

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

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)

Demonstration Purpose

This pull request serves as a demonstration of the potential impact of changes in GORM's behavior, particularly in relation to preloading and joining operations. It provides an opportunity to understand how these changes might affect database efficiency and application performance.