# Source: https://mikro-orm.io/docs/loading-strategies.md

# Relationship Loading Strategies

MikroORM supports three loading strategies:

* `select-in` which uses separate queries for each relation - it you populate two relations, you will get three queries - one for the root entity, and one for each populated relation.
* `joined` which uses a single query and joins the relations instead.
* `balanced` which joins `to-one` relations and uses `select-in` for `to-many` relations.

> `joined` strategy is supported **only in SQL drivers** and is the **default** for those since v6.

> `combined` strategy will be the default in v7.

## Configuring the strategy[​](#configuring-the-strategy "Direct link to Configuring the strategy")

The loading strategy can be specified both at mapping time and when loading entities, as well as globally in your ORM config.

Given the following entities:

```
import { Entity, LoadStrategy, OneToMany, ManyToOne, PrimaryKey } from '@mikro-orm/core';

@Entity()
export class Author {

  @PrimaryKey()
  id!: number;

  @OneToMany(() => Book, b => b.author)
  books = new Collection<Book>(this);

}

@Entity()
export class Book {

  @PrimaryKey()
  id!: number;

  @ManyToOne()
  author: Author;

  @ManyToOne(() => Book, { nullable: true })
  inspiredBy?: Book;

}
```

With the default `joined` strategy, this will issue a single query, loading the `Author` entity and its `books` and `books.inspiredBy` relations.

```
const author = await orm.em.findOne(Author, 1, {
  populate: ['books.inspiredBy'],
});
```

To override the strategy, you can use the `strategy` option:

```
const author = await orm.em.findOne(Author, 1, {
  populate: ['books.inspiredBy'],
  strategy: 'select-in',
});
```

This will issue three SQL statements, one to load the author, another to load all the books belonging to that author, and a third one fetching the `Book.inspiredBy` relation.

With the `balanced` strategy, this example would use two queries, one for the `Author` entities, the other for their books, including the `inspiredBy` relation:

```
const author = await orm.em.findOne(Author, 1, {
  populate: ['books.inspiredBy'],
  strategy: 'balanced',
});
```

Alternatively, you can control the strategy in your entity definition.

```
import { Entity, LoadStrategy, OneToMany } from '@mikro-orm/core';

@Entity()
export class Author {

  // ...

  @OneToMany({
    entity: () => Book,
    mappedBy: b => b.author,
    strategy: 'select-in', // force select-in strategy for this relation
  })
  books = new Collection<Book>(this);

}
```

The strategy defined on property level will always take a precedence.

## Changing the loading strategy globally[​](#changing-the-loading-strategy-globally "Direct link to Changing the loading strategy globally")

You can use `loadStrategy` option in the ORM config:

```
MikroORM.init({
  // ...
  populate: ['books'],
  loadStrategy: 'select-in', // 'joined' is the default for SQL drivers
});
```

This value will be used as the default, specifying the loading strategy on property level has precedence, as well as specifying it in the `FindOptions`.

## Population `where` condition[​](#population-where-condition "Direct link to population-where-condition")

The where condition is by default applied only to the root entity. This can be controlled via `populateWhere` option. It accepts one of `all` (default), `infer` (use same condition as the `where` query) or an explicit filter query.

```
await em.find(Author, { ... }, {
  populate: ['books'],
  populateWhere: 'infer', // defaults to `all`

  // or specify custom query, will be used via `join on` conditions
  // populateWhere: { age: { $gte: 18 } },
});
```

> `populateWhere` can be also set globally, the default is `all`.

## Population `order by` clause[​](#population-order-by-clause "Direct link to population-order-by-clause")

Similarly to the `populateWhere`, you can also control the `order by` clause used for the populate queries. The default behaviour is to use the same ordering as for the root entity, and you can use `populateOrderBy` option to add a different ordering:

```
await em.find(Author, { ... }, {
  populate: ['books'],
  populateOrderBy: { books: { publishedAt: 'desc' } },
});
```