我编写了这个SQL查询,并将其用作hibernate中的原生查询。
@Query(
value = "SELECT DISTINCT tp.* FROM TWITTER_POST AS tp " +
"JOIN TWITTER_LIST AS tl " +
"ON tl.owner_id = ?1 " +
"JOIN REL_TWITTER_LIST__ACCOUNTS_TRACKED_BY_LIST AS atbl " +
"ON tl.id = atbl.twitter_list_id " +
"JOIN TWITTER_ACCOUNT AS ta " +
"ON ta.id = atbl.accounts_tracked_by_list_id " +
"LEFT OUTER JOIN REL_TWITTER_POST__TWITTER_USERS_HIDING_POST uhp " +
"ON tp.id = uhp.twitter_post_id " +
"AND uhp.TWITTER_USERS_HIDING_POST_ID = ?1 " +
"WHERE uhp.twitter_post_id is NULL AND ta.id = tp.author_id",
countQuery = "SELECT DISTINCT count(tp.*) FROM TWITTER_POST AS tp " +
"JOIN TWITTER_LIST AS tl " +
"ON tl.owner_id = ?1 " +
"JOIN REL_TWITTER_LIST__ACCOUNTS_TRACKED_BY_LIST AS atbl " +
"ON tl.id = atbl.twitter_list_id " +
"JOIN TWITTER_ACCOUNT AS ta " +
"ON ta.id = atbl.accounts_tracked_by_list_id " +
"LEFT OUTER JOIN REL_TWITTER_POST__TWITTER_USERS_HIDING_POST uhp " +
"ON tp.id = uhp.twitter_post_id " +
"AND uhp.TWITTER_USERS_HIDING_POST_ID = ?1 " +
"WHERE uhp.twitter_post_id is NULL AND ta.id = tp.author_id",
nativeQuery = true
)
Page<TwitterPost> findAllNonHiddenForListsFromTwitterAccountId(Long twitterAccountId, Pageable pageable);我注意到,当我通过hibernate (而不是SQL工具)运行查询时,查询执行得非常慢。我认为这是因为我使用的是本机查询,而不是JQPL,JQPL(据我所读)立即进行缓存和分页,而不需要定义"count“。试图将其转换为JQPL失败了,因为我找不到更复杂的JQPL跨联接表查询的好教程。
@Query(
value = "SELECT DISTINCT twitterPost " +
"FROM TwitterPost twitterPost " +
"JOIN TwitterList twitterList " +
"ON twitterList.owner.id = ?1 " +
"JOIN TwitterAccount tweetAuthorFromList " +
"ON tweetAuthorFromList IN twitterList.accountsTrackedByLists " +
"WHERE twitterPost.author = tweetAuthorFromList " +
"AND twitterList.owner NOT IN twitterPost.twitterUsersHidingPosts"
)
Page<TwitterPost> findAllNonHiddenPostsFromListsForTwitterAccountId(Long twitterAccountId, Pageable pageable);很明显我的语法没了
org.hibernate.exception.SQLGrammarException:无法准备语句
但是编译器只显示生成的SQL的问题,而不是JQPL,所以我被蒙在鼓里。
此外,还检查了典型的不良性能缺陷,即对实体的急切抓取,而我将这些实体设置为到处都是懒惰的。
任何关于我的性能问题假设是否正确或转换查询的帮助都是非常感谢的--谢谢!
发布于 2021-11-10 18:23:15
这里有很多不对的地方:
使用SELECT
ON tl.owner_id = ?1是为了过滤,而不是为了投影,因此您最好执行一个存在的ON tl.owner_id = ?1,为什么查询运行缓慢而不是分析它。它之所以在DB工具中运行得更快,是因为DB工具通常会截断结果集,而Spring数据则会消耗整个结果集。或者,如果您运行EXPLAIN,输出可能来自优化器,甚至不运行查询.。
所以,你能做的是:
在JDBC驱动程序级别使用半连接而不是filtering.
Blaze Persistence来编写更好的实体查询dynamically.
https://stackoverflow.com/questions/69918223
复制相似问题