Merge branch '28492-add-dev-documentation-for-using-the-queryrecorder-in-specs' into 'master'
Adds docs for QueryRecorder tests Closes #28492 See merge request !9838
This commit is contained in:
commit
db3c2c2331
4 changed files with 35 additions and 1 deletions
|
@ -68,7 +68,7 @@ end
|
||||||
This will end up running one query for every object to update. This code can
|
This will end up running one query for every object to update. This code can
|
||||||
easily overload a database given enough rows to update or many instances of this
|
easily overload a database given enough rows to update or many instances of this
|
||||||
code running in parallel. This particular problem is known as the
|
code running in parallel. This particular problem is known as the
|
||||||
["N+1 query problem"](http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations).
|
["N+1 query problem"](http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations). You can write a test with [QueryRecoder](query_recorder.md) to detect this and prevent regressions.
|
||||||
|
|
||||||
In this particular case the workaround is fairly easy:
|
In this particular case the workaround is fairly easy:
|
||||||
|
|
||||||
|
@ -117,6 +117,8 @@ Post.all.includes(:author).each do |post|
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Also consider using [QueryRecoder tests](query_recorder.md) to prevent a regression when eager loading.
|
||||||
|
|
||||||
## Memory Usage
|
## Memory Usage
|
||||||
|
|
||||||
**Summary:** merge requests **must not** increase memory usage unless absolutely
|
**Summary:** merge requests **must not** increase memory usage unless absolutely
|
||||||
|
|
|
@ -39,6 +39,7 @@ GitLab provides built-in tools to aid the process of improving performance:
|
||||||
* [Sherlock](profiling.md#sherlock)
|
* [Sherlock](profiling.md#sherlock)
|
||||||
* [GitLab Performance Monitoring](../administration/monitoring/performance/introduction.md)
|
* [GitLab Performance Monitoring](../administration/monitoring/performance/introduction.md)
|
||||||
* [Request Profiling](../administration/monitoring/performance/request_profiling.md)
|
* [Request Profiling](../administration/monitoring/performance/request_profiling.md)
|
||||||
|
* [QueryRecoder](query_recorder.md) for preventing `N+1` regressions
|
||||||
|
|
||||||
GitLab employees can use GitLab.com's performance monitoring systems located at
|
GitLab employees can use GitLab.com's performance monitoring systems located at
|
||||||
<http://performance.gitlab.net>, this requires you to log in using your
|
<http://performance.gitlab.net>, this requires you to log in using your
|
||||||
|
|
|
@ -25,3 +25,5 @@ starting GitLab. For example:
|
||||||
|
|
||||||
Bullet will log query problems to both the Rails log as well as the Chrome
|
Bullet will log query problems to both the Rails log as well as the Chrome
|
||||||
console.
|
console.
|
||||||
|
|
||||||
|
As a follow up to finding `N+1` queries with Bullet, consider writing a [QueryRecoder test](query_recorder.md) to prevent a regression.
|
||||||
|
|
29
doc/development/query_recorder.md
Normal file
29
doc/development/query_recorder.md
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# QueryRecorder
|
||||||
|
|
||||||
|
QueryRecorder is a tool for detecting the [N+1 queries problem](http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations) from tests.
|
||||||
|
|
||||||
|
> Implemented in [spec/support/query_recorder.rb](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/spec/support/query_recorder.rb) via [9c623e3e](https://gitlab.com/gitlab-org/gitlab-ce/commit/9c623e3e5d7434f2e30f7c389d13e5af4ede770a)
|
||||||
|
|
||||||
|
As a rule, merge requests [should not increase query counts](merge_request_performance_guidelines.md#query-counts). If you find yourself adding something like `.includes(:author, :assignee)` to avoid having `N+1` queries, consider using QueryRecorder to enforce this with a test. Without this, a new feature which causes an additional model to be accessed will silently reintroduce the problem.
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
This style of test works by counting the number of SQL queries executed by ActiveRecord. First a control count is taken, then you add new records to the database and rerun the count. If the number of queries has significantly increased then an `N+1` queries problem exists.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
it "avoids N+1 database queries" do
|
||||||
|
control_count = ActiveRecord::QueryRecorder.new { visit_some_page }.count
|
||||||
|
create_list(:issue, 5)
|
||||||
|
expect { visit_some_page }.not_to exceed_query_limit(control_count)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
As an example you might create 5 issues in between counts, which would cause the query count to increase by 5 if an N+1 problem exists.
|
||||||
|
|
||||||
|
> **Note:** In some cases the query count might change slightly between runs for unrelated reasons. In this case you might need to test `exceed_query_limit(control_count + acceptable_change)`, but this should be avoided if possible.
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [Bullet](profiling.md#Bullet) For finding `N+1` query problems
|
||||||
|
- [Performance guidelines](performance.md)
|
||||||
|
- [Merge request performance guidelines](merge_request_performance_guidelines.md#query-counts)
|
Loading…
Reference in a new issue