当 GraphQL 查询只需要返回对象的某些字段时,为啥 MySQL/Sequelize 会执行全选查询?
Posted
技术标签:
【中文标题】当 GraphQL 查询只需要返回对象的某些字段时,为啥 MySQL/Sequelize 会执行全选查询?【英文标题】:Why does MySQL/Sequelize perform full select queries when a GraphQL query only requires certain fields of an object to be returned?当 GraphQL 查询只需要返回对象的某些字段时,为什么 MySQL/Sequelize 会执行全选查询? 【发布时间】:2020-11-18 00:11:08 【问题描述】:对于我的应用程序中的用户,我有一个类似这样的简单架构:
type Query
users: [User!]!
# The User ObjectType and Sequelize model.
type User implements UserI
id: ID!
userName: String!
firstName: String!
lastName: String!
email: String!
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime!
我的type-graphql
解析器实现了这个简单的代码来返回users
的列表:
@Resolver()
class UserResolver
@Query(() => [User])
async users(): Promise<User[]>
return User.findAll();
当我执行这样的查询时:
users
firstName
我预计等效的 mysql 查询会是这样的:SELECT firstName FROM users
,但我可以看到 Sequelize 将查询记录为:
Executing (default): SELECT `id`, `userName`, `firstName`, `lastName`, `email`, `password`, `createdAt`, `updatedAt` FROM `users` AS `User` WHERE (`User`.`deletedAt` IS NULL);
现在,虽然一切正常(我可以在客户端获取所有用户及其数据),但我想知道如果 Sequelize 执行完整的属性选择,是否会对服务器端的性能造成影响?这是由于 Sequelize 还是仅仅由于 GraphQL 如何解析模型字段?我错过了一些选项吗?
【问题讨论】:
【参考方案1】:我错过了一些选择吗?
您需要将 GraphQL 查询(请求)翻译成正确的 SQL 查询。只是调用findAll()
没有关于请求的任何信息,因此它正确地获取了完整的实体。
基本上,您需要将 GraphQL Resolve Info 解析为更易读的格式(例如使用https://www.npmjs.com/package/graphql-fields),然后为 TypeORM 构建一个select
选项(例如.findAll( select: ['id'] )
)。
【讨论】:
以上是关于当 GraphQL 查询只需要返回对象的某些字段时,为啥 MySQL/Sequelize 会执行全选查询?的主要内容,如果未能解决你的问题,请参考以下文章
GraphQL 使用 Introspection 时某些字段没有类型名称?
查询不会通过 GraphQL 从 DynamoDB 返回某些项目