使用和不使用缓存,sequelize 都很慢
sequelize is slow with and without caching
我有以下续集代码:
async function findAllRatePlans() {
return await db.rate_plans.cache('all').findAll({
include: [
{ model: db.pricings },
{ model: db.services },
{ model: db.usps_evs_accounts }
]
});
}
这会产生以下查询(无缓存):
SELECT
"rate_plans"."id",
"rate_plans"."tag",
"rate_plans"."service_id" AS "serviceId",
...
"pricing"."id" AS "pricing.id",
"pricing"."name" AS "pricing.name",
"pricing"."api_name" AS "pricing.apiName",
...
"usps_evs_account"."id" AS "usps_evs_account.id",
"usps_evs_account"."default" AS "usps_evs_account.default",
...
FROM "rate_plans" AS "rate_plans"
LEFT OUTER JOIN "pricings" AS "pricing" ON "rate_plans"."pricing_id" = "pricing"."id"
LEFT OUTER JOIN "services" AS "service" ON "rate_plans"."service_id" = "service"."id"
LEFT OUTER JOIN "usps_evs_accounts" AS "usps_evs_account" ON "rate_plans"."nsa_usps_evs_account_id" = "usps_evs_account"."id"
select 语句中大约有 50 列。
A rate_plan 定义为 belongsTo 定价、belongsTo 服务和 belongsTo usps_evs_accounts。
这是我的第一个主要 Node 和 sequelize 项目,我正试图找出为什么代码 运行 这么慢。我添加了 newrelic 模块来检测事物,看起来 sequelize 调用非常慢。最初我直接点击数据库,但后来我安装了 sequelize-transparent-cache;不幸的是,这对整体性能影响不大。 NewRelic 显示 findAllRatePlans()
函数(使用缓存时)需要 62.32 毫秒。也许我对 Node 的期望是错误的,但我认为这应该快得多。我在 Ruby 中有相同的代码,而且 运行 快了 10 倍。我在这里遗漏了什么吗?
原来这个 SQL 查询不够具体,它最终返回了大约 1000 行,所以大约有 50,000 个字段。总之,这大约是 2MB 的数据被序列化为 Javascript 个对象。我的问题还在于代码总体上非常面向对象,有很多域对象。我认为 sequelize-transparent-cache 缓存原始数据而不是 Javascript 对象。我最终编写了自己的 Redis 缓存,它序列化了 Javascript 个对象,并且我获得了性能提升,但是我无法存储对象类型,所以我仍然不得不做一个新对象 1000 次。 ActiveRecord 和缓存机制在序列化和反序列化期间更好地跟踪对象类型。最后,在我原来的 SQL 查询中添加更多的 where 子句导致记录减少并大大提高了性能。
我有以下续集代码:
async function findAllRatePlans() {
return await db.rate_plans.cache('all').findAll({
include: [
{ model: db.pricings },
{ model: db.services },
{ model: db.usps_evs_accounts }
]
});
}
这会产生以下查询(无缓存):
SELECT
"rate_plans"."id",
"rate_plans"."tag",
"rate_plans"."service_id" AS "serviceId",
...
"pricing"."id" AS "pricing.id",
"pricing"."name" AS "pricing.name",
"pricing"."api_name" AS "pricing.apiName",
...
"usps_evs_account"."id" AS "usps_evs_account.id",
"usps_evs_account"."default" AS "usps_evs_account.default",
...
FROM "rate_plans" AS "rate_plans"
LEFT OUTER JOIN "pricings" AS "pricing" ON "rate_plans"."pricing_id" = "pricing"."id"
LEFT OUTER JOIN "services" AS "service" ON "rate_plans"."service_id" = "service"."id"
LEFT OUTER JOIN "usps_evs_accounts" AS "usps_evs_account" ON "rate_plans"."nsa_usps_evs_account_id" = "usps_evs_account"."id"
select 语句中大约有 50 列。
A rate_plan 定义为 belongsTo 定价、belongsTo 服务和 belongsTo usps_evs_accounts。
这是我的第一个主要 Node 和 sequelize 项目,我正试图找出为什么代码 运行 这么慢。我添加了 newrelic 模块来检测事物,看起来 sequelize 调用非常慢。最初我直接点击数据库,但后来我安装了 sequelize-transparent-cache;不幸的是,这对整体性能影响不大。 NewRelic 显示 findAllRatePlans()
函数(使用缓存时)需要 62.32 毫秒。也许我对 Node 的期望是错误的,但我认为这应该快得多。我在 Ruby 中有相同的代码,而且 运行 快了 10 倍。我在这里遗漏了什么吗?
原来这个 SQL 查询不够具体,它最终返回了大约 1000 行,所以大约有 50,000 个字段。总之,这大约是 2MB 的数据被序列化为 Javascript 个对象。我的问题还在于代码总体上非常面向对象,有很多域对象。我认为 sequelize-transparent-cache 缓存原始数据而不是 Javascript 对象。我最终编写了自己的 Redis 缓存,它序列化了 Javascript 个对象,并且我获得了性能提升,但是我无法存储对象类型,所以我仍然不得不做一个新对象 1000 次。 ActiveRecord 和缓存机制在序列化和反序列化期间更好地跟踪对象类型。最后,在我原来的 SQL 查询中添加更多的 where 子句导致记录减少并大大提高了性能。