我有以下 hql 查询:
@Query("SELECT es FROM EmailSubscription es "
+ "JOIN FETCH es.subscriber s "
+ "WHERE es.subscriptionTypeId = :typeId "
+ "AND es.active = :active "
+ "AND es.id > :batchStartId "
+ "ORDER BY es.id ASC")
@QueryHints(@QueryHint(name = "org.hibernate.fetchSize", value = "1000"))
不幸的是,加载 EmailSubscription 及其关系订阅者需要大约 2 秒以上的时间来获取 1k 条记录。
此本机 sql 查询在 500 毫秒内完成,但由于它是本机 sql,因此不会加载其关系(订阅者)。
@Query(value = "SELECT es.* FROM subscriptions.email_subscriptions es "
+ "IGNORE INDEX (PRIMARY) "
+ "JOIN subscriptions.subscribers s ON es.subscriber_id = s.id "
+ "WHERE es.type_id = :typeId "
+ "AND es.active = :active "
+ "AND es.id > :batchStartId "
+ "ORDER BY es.id ", nativeQuery = true)
有没有办法可以在 hql 查询中强制使用索引或选择忽略主索引?
除非我弄错了,否则您正在比较两种不同数据库工作负载的性能。 hibernate 查询正在运行 Join Fetch 以检索相关订阅者详细信息,这可能会为每个电子邮件订阅的每个单独订阅者运行额外的 SQL 查询。
因此,您正在查看类似 N * M 的数据,即提交到数据库的查询数量。其中 N 是电子邮件订阅的数量,M 是每个电子邮件订阅的订阅者数量。相比之下,本机查询向数据库提交单个请求。
如果您为订阅者获取配置批量大小,您可以将其减少到类似 N * M/BatchSize