查询次数限制
每个控制器、API 端点和 Sidekiq worker 最多允许执行 100 次 SQL 查询。 如果执行的 SQL 查询超过 100 次,这是一个需要修复的 性能问题。
解决失败的测试
在测试环境中,当超过这个阈值时,我们会抛出一个错误。
当一个测试因为执行了超过 100 次 SQL 查询而失败时,这个问题有两种解决方案:
- 减少执行的 SQL 查询次数。
- 临时禁用该控制器或 API 端点的查询次数限制。
您应该只在不得已的情况下禁用查询次数限制,例如当问题出在现有控制器或端点上时,因为减少其 SQL 查询次数可能需要大量工作。新添加的控制器和端点则不允许执行超过 100 次 SQL 查询,此规则没有例外。
流水线稳定性
如果测试用例在默认分支的流水线中开始出现查询次数限制错误,请按照 说明 来禁用查询次数限制。 禁用限制时,必须关联并优先处理一个 issue,以便对过多的查询量进行调查。
禁用查询次数限制
如果您必须为某个控制器禁用查询次数限制,您必须首先创建一个 issue。这个 issue(最好在标题中)应提及该控制器或端点,并包含相应的标签(如 database、performance 以及至少一个团队特定的标签,例如 Discussion)。
自 GitLab 17.2 起,QueryLimiting.disable 必须设置一个新的阈值(而不是无限制)。
创建 issue 后,您就可以对相关代码禁用查询次数限制。对于 Rails 控制器,最好是创建一个 before_action 钩子,让它尽早运行。被调用的方法接着应该调用 Gitlab::QueryLimiting.disable!('issue 的 URL 地址')。例如:
class MyController < ApplicationController
before_action :disable_query_limiting, only: [:show]
def index
# ...
end
def show
# ...
end
def disable_query_limiting
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/...', new_threshold: 200)
end
end通过使用 before_action,您无需修改相关的控制器方法,从而降低了合并冲突的可能性。
对于 Grape API 端点,不幸的是,没有可靠的方法可以在特定端点之前运行钩子。这意味着您必须将允许列表的调用直接添加到端点中,如下所示:
get '/projects/:id/foo' do
Gitlab::QueryLimiting.disable!('...', new_threshold: 200)
# ...
end对于 Sidekiq worker,您也需要直接添加允许列表:
def perform(args)
Gitlab::QueryLimiting.disable!('...', new_threshold: 200)
# ...
end