【发布时间】:2021-03-31 15:52:10
【问题描述】:
我有一个在 Ubuntu 上运行的 Rails 5.2 应用程序,它与一个包含超过 5000 万条记录的大型 MySQL 数据库配合使用。
用户在数据库上执行搜索。在可接受的时间范围内执行特定搜索。
但是,默认是完整的通配符搜索,以返回第一个(例如 50 条)记录,按一个或多个字段排序(排序)。
默认通配符搜索可能需要相当长的时间,但是一旦执行,结果就会被缓存,重复通配符搜索非常快。
通常结果仍然缓存,但有时缓存会被刷新,并且必须再次执行搜索,这又需要很长时间。缓存总是在早上刷新,我将其归因于服务器/数据库在夜间备份,或者云服务器实例以某种方式刷新。
好的,我想,我将运行一个定期(每小时)运行的 cronjob 并重新填充缓存。所以这就是我所做的,并且我很小心地实际执行搜索(不仅仅是创建一个实际上没有执行的 Active Record 查询)。
cronjob 调用模型中的一个方法来执行数据库查询(并丢弃结果)。我可以从日志中看到执行了搜索。
不幸的是,这种填充缓存的尝试似乎并没有使提取相同数据的 HTTP RESTful API 受益。一段时间内的第一个通配符查询总是需要很长时间,即使最近运行了一个 cronjob 填充缓存任务。但是,同样,一旦 RESTful API 搜索完成,相同查询的后续重复会很快返回缓存的响应。
也许 RESTful 查询未被识别为与在 cronjob 中执行的相同搜索?
关于如何填充缓存并保持填充的建议表示赞赏。
更新
Rails 生成的用于查询的 SQL,
SELECT `products`.*
FROM `products`
WHERE `products`.`category` = 0
AND `products`.`available` = TRUE
ORDER BY LENGTH(prefix) ASC,
LENGTH(numbers) ASC,
LENGTH(suffix) ASC,
`products`.`prefix` ASC,
`products`.`numbers` ASC,
`products`.`suffix` ASC
LIMIT 20 OFFSET 0
架构的相关部分,
create_table "products", force: :cascade do |t|
t.integer "category"
t.string "prefix"
t.string "numbers"
t.string "suffix"
t.boolean "available", default: false
t.integer "user_id"
t.integer "price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "open_sale", default: false
t.index ["category", "prefix", "numbers", "suffix"], name: "index_products_category_prefix_numbers_suffix"
end
【问题讨论】:
-
请向我们展示所涉及的 SQL 以及架构 (
SHOW CREATE TABLE) -
@RickJames 按要求添加。谢谢!
标签: mysql ruby-on-rails