Skip to content

Commit 2eb4f45

Browse files
committed
Update default eager loading strategy to subquery
Document the change from 'select' to 'subquery' as the default eager loading strategy for HasMany and BelongsToMany associations. Refs cakephp/cakephp#19345
1 parent 27cfdc9 commit 2eb4f45

2 files changed

Lines changed: 27 additions & 13 deletions

File tree

docs/en/appendices/5-4-migration-guide.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,21 @@ bin/cake upgrade rector --rules cakephp54 <path/to/app/src>
1616

1717
## Behavior Changes
1818

19-
- WIP
19+
### ORM
20+
21+
The default eager loading strategy for `HasMany` and `BelongsToMany` associations
22+
has changed from ``select`` to ``subquery``. The ``subquery`` strategy performs
23+
better for larger datasets as it avoids packet size limits from large ``WHERE IN``
24+
clauses and reduces PHP memory usage by keeping IDs in the database.
25+
26+
If you need the previous behavior, you can explicitly set the strategy when
27+
defining associations:
28+
29+
```php
30+
$this->hasMany('Comments', [
31+
'strategy' => 'select',
32+
]);
33+
```
2034

2135
## Deprecations
2236

docs/en/orm/associations.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -462,9 +462,9 @@ Possible keys for hasMany association arrays include:
462462
- **propertyName**: The property name that should be filled with data from the
463463
associated table into the source table results. By default, this is the
464464
underscored & plural name of the association so `comments` in our example.
465-
- **strategy**: Defines the query strategy to use. Defaults to 'select'. The
466-
other valid value is 'subquery', which replaces the `IN` list with an
467-
equivalent subquery.
465+
- **strategy**: Defines the query strategy to use. Defaults to 'subquery'. The
466+
other valid value is 'select', which uses the `IN` list of parent keys
467+
directly instead of a subquery.
468468
- **saveStrategy**: Either `append` or `replace`. Defaults to `append`. When `append` the current
469469
records are appended to any records in the database. When `replace` associated
470470
records not in the current set will be removed. If the foreign key is a nullable
@@ -487,15 +487,15 @@ The above would output SQL similar to:
487487

488488
```sql
489489
SELECT * FROM articles;
490-
SELECT * FROM comments WHERE article_id IN (1, 2, 3, 4, 5);
490+
SELECT * FROM comments WHERE article_id IN (SELECT id FROM articles);
491491
```
492492

493-
When the subquery strategy is used, SQL similar to the following will be
493+
When the select strategy is used, SQL similar to the following will be
494494
generated:
495495

496496
```sql
497497
SELECT * FROM articles;
498-
SELECT * FROM comments WHERE article_id IN (SELECT id FROM articles);
498+
SELECT * FROM comments WHERE article_id IN (1, 2, 3, 4, 5);
499499
```
500500

501501
You may want to cache the counts for your hasMany associations. This is useful
@@ -616,9 +616,9 @@ Possible keys for belongsToMany association arrays include:
616616
- **propertyName**: The property name that should be filled with data from the
617617
associated table into the source table results. By default, this is the
618618
underscored & plural name of the association, so `tags` in our example.
619-
- **strategy**: Defines the query strategy to use. Defaults to 'select'. The
620-
other valid value is 'subquery', which replaces the `IN` list with an
621-
equivalent subquery.
619+
- **strategy**: Defines the query strategy to use. Defaults to 'subquery'. The
620+
other valid value is 'select', which uses the `IN` list of parent keys
621+
directly instead of a subquery.
622622
- **saveStrategy**: Either `append` or `replace`. Defaults to `replace`.
623623
Indicates the mode to be used for saving associated entities. The former will
624624
only create new links between both side of the relation and the latter will
@@ -645,19 +645,19 @@ SELECT * FROM articles;
645645
SELECT * FROM tags
646646
INNER JOIN articles_tags ON (
647647
tags.id = article_tags.tag_id
648-
AND article_id IN (1, 2, 3, 4, 5)
648+
AND article_id IN (SELECT id FROM articles)
649649
);
650650
```
651651

652-
When the subquery strategy is used, SQL similar to the following will be
652+
When the select strategy is used, SQL similar to the following will be
653653
generated:
654654

655655
```sql
656656
SELECT * FROM articles;
657657
SELECT * FROM tags
658658
INNER JOIN articles_tags ON (
659659
tags.id = article_tags.tag_id
660-
AND article_id IN (SELECT id FROM articles)
660+
AND article_id IN (1, 2, 3, 4, 5)
661661
);
662662
```
663663

0 commit comments

Comments
 (0)