如何正确搭配PlanetScale与Fastify?Node.js查询性能优化疑问
问题原因
你遇到的核心问题是单个MySQL连接无法并行处理多个查询——即使你用了Promise.all,所有查询都在同一个连接上排队执行,总耗时自然是单个查询的倍数。
Laravel/WordPress的底层查询机制默认会利用连接池的多个连接来并行处理查询,所以你之前没遇到过这种线性耗时的情况,但Node.js里的mysql2(@fastify/mysql基于它封装)单个连接本身是串行执行查询的。
无需重构SQL的优化方案
下面两种方案都不用改SQL,直接解决并行执行问题:
方案1:用连接池的多个独立连接执行查询
从连接池获取多个连接,每个查询用单独的连接,这样数据库就能并行处理:
export async function someFunction(fastify, id) { if (!validator.isNumeric(id)) { throw new Error('Invalid slug'); } // 并行获取三个连接 const [connA, connB, connC] = await Promise.all([ fastify.mysql.getConnection(), fastify.mysql.getConnection(), fastify.mysql.getConnection() ]); try { // 每个查询用独立连接,并行执行 const [[a], [b], c] = await Promise.all([ connA.query(a_query, [id]), connB.query(b_query, [id]), connC.query(c_query, [id]) ]); return { a, b }; } finally { // 确保所有连接都释放回池,避免泄漏 connA.release(); connB.release(); connC.release(); } }
方案2:直接使用fastify.mysql.query(推荐)
@fastify/mysql提供的顶层query方法会自动从连接池取空闲连接,执行完后自动释放。每个query调用会使用独立的连接,天然支持并行:
export async function someFunction(fastify, id) { if (!validator.isNumeric(id)) { throw new Error('Invalid slug'); } // 直接用fastify.mysql的query,每个请求自动用池里的独立连接 const [[a], [b], c] = await Promise.all([ fastify.mysql.query(a_query, [id]), fastify.mysql.query(b_query, [id]), fastify.mysql.query(c_query, [id]) ]); return { a, b }; }
额外优化:调整连接池配置
可以在注册@fastify/mysql时显式配置连接池大小,确保有足够的空闲连接处理并行请求:
app.register(fastifyMysql, { uri: process.env.DATABASE_URL, type: 'pool', promise: true, multipleStatements: false, // 配置连接池参数,根据你的并发需求调整 pool: { min: 3, // 最小空闲连接数 max: 10 // 最大连接数 } });
内容的提问来源于stack exchange,提问作者Falcon
相关产品推荐
相关产品推荐

