-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add notes about Doctrine performances #107
Conversation
|
||
### Search Filter | ||
|
||
When using the `SearchFilter` and case insensivity, Doctrine will be using the `LOWER` sql function. Depending on your driver, you may want to carefully index it by using a [*function-based index*](http://use-the-index-luke.com/sql/where-clause/functions/case-insensitive-search) or it will impact performances with a huge collection. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doctrine will use ... SQL
Also, we should probably note that function-based index alone is not enough for good performance. When using PostgreSQL for example, it's necessary to add a text_pattern_ops
index, and also gin_trgm_ops
(from pg_trgm
). But perhaps it's out of scope... 😛
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e.g.:
CREATE INDEX idx_places_name_trgm ON places USING GIN (lower(name) gin_trgm_ops);
CREATE INDEX idx_places_name_pattern ON places (lower(name) text_pattern_ops);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's out of scope (because it's Driver-dependent) but I totaly agree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps add this link: http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning
527d43e
to
b0e7d7f
Compare
Comments addressed thx @teohhanhui |
Even though we're selecting only partial results (serialized properties) with Doctrine, it'll try to hydrate some relations with lazy joins (for example `OneToOne` relations). It's recommended to take a look at the Symfony Profiler, check what the generated SQL queries are doing in background and see if those may impact performance. | ||
|
||
To force Doctrine to only hydrate partial values you need to use the [`Query::HINT_FORCE_PARTIAL_LOAD`](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#query-hints). | ||
Be careful, using this query hint will force the use of partial selects. Some properties might not be available even if you expect them. If you want to be sure that Doctrine fetches them, use Eager joins and make sure that properties are serializable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New paragraph? Missing line break.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's linked to the previous one, I'd keep it like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want a newline without starting a new paragraph, you need to add two trailing spaces on the previous line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving it like this is really confusing...
b0e7d7f
to
337ce4d
Compare
I think I have to wrap lines manually? What's the limit? |
337ce4d
to
0fccb27
Compare
Yes, it's better to use hard line wrapping in Markdown (it's designed with that in mind after all). Currently I think we're going for 120 characters. |
0fccb27
to
565c6ec
Compare
@soyuka is this PR ready for merging? |
yes |
@@ -23,7 +23,7 @@ The search filter supports `exact`, `partial`, `start`, `end`, and `word_start` | |||
* `word_start` strategy uses `LIKE text% OR LIKE % text%` to search for fields that contains the word starting with `text`. | |||
|
|||
Prepend the letter `i` to the filter if you want it to be case insensitive. For example `ipartial` or `iexact`. Note that | |||
this will use the `LOWER` function and **will** impact performances if there is no [*function-based index*](http://use-the-index-luke.com/sql/where-clause/functions/case-insensitive-search). | |||
this will use the `LOWER` function and **will** impact performances [if there is no proper index](performance.md#search-filter). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
performance (uncountable)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still this one to fix.
|
||
When using the `SearchFilter` and case insensivity, Doctrine will use the `LOWER` SQL function. Depending on your | ||
driver, you may want to carefully index it by using a [function-based | ||
index](http://use-the-index-luke.com/sql/where-clause/functions/case-insensitive-search) or it will impact performances |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
performance (uncountable)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too
a364dfa
to
d794318
Compare
This one should be good to go |
[`PaginationExtension`](https://github.com/api-platform/core/blob/master/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php) | ||
by setting the query hint: | ||
|
||
```php |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should include <?php
now.
|
||
```yaml | ||
# app/config/services.yml | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll keep the services:
key to make it copy/pastable.
To alter the `Query` object on an item data provider, we can also create an `QueryHintExtension` which will alter the result: | ||
|
||
```php | ||
// src/AppBundle/Doctrine/Orm/Extension/QueryHintExtension.php |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should include <?php
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -23,7 +23,7 @@ The search filter supports `exact`, `partial`, `start`, `end`, and `word_start` | |||
* `word_start` strategy uses `LIKE text% OR LIKE % text%` to search for fields that contains the word starting with `text`. | |||
|
|||
Prepend the letter `i` to the filter if you want it to be case insensitive. For example `ipartial` or `iexact`. Note that | |||
this will use the `LOWER` function and **will** impact performances if there is no [*function-based index*](http://use-the-index-luke.com/sql/where-clause/functions/case-insensitive-search). | |||
this will use the `LOWER` function and **will** impact performances [if there is no proper index](performance.md#search-filter). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still this one to fix.
|
||
When using the `SearchFilter` and case insensivity, Doctrine will use the `LOWER` SQL function. Depending on your | ||
driver, you may want to carefully index it by using a [function-based | ||
index](http://use-the-index-luke.com/sql/where-clause/functions/case-insensitive-search) or it will impact performances |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too
$this->managerRegistry = $managerRegistry; | ||
$this->decorated = $decorated; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extra blank line
} | ||
|
||
/** | ||
* @inheritdoc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{@inheritdoc}
|
||
|
||
/** | ||
* @inheritdoc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{@inheritdoc}
use Doctrine\ORM\Tools\Pagination\Paginator as DoctrineOrmPaginator; | ||
use Doctrine\ORM\Query; | ||
|
||
class QueryHintPaginationExtension implements QueryResultCollectionExtensionInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make this class final
please?
|
||
To force Doctrine to only hydrate partial values you need to use the | ||
[`Query::HINT_FORCE_PARTIAL_LOAD`](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#query-hints). | ||
Be careful, using this query hint will force the use of partial selects. Some properties might not be available even if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra space to remove at the start of the line
To force Doctrine to only hydrate partial values you need to use the | ||
[`Query::HINT_FORCE_PARTIAL_LOAD`](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#query-hints). | ||
Be careful, using this query hint will force the use of partial selects. Some properties might not be available even if | ||
you expect them. If you want to be sure that Doctrine fetches them, use Eager joins and make sure that properties are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eager (no reason to have an uppercase E)
} | ||
|
||
/** | ||
* @inheritdoc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{@inheritdoc}
thanks, updated |
Thanks @soyuka |
thanks @teohhanhui @dunglas for the review! |
ping @teohhanhui