[英]Improving performance of Solr and MySQL pair (connected by “WHERE IN” using JPA)
我有一个由Solr索引的MySQL数据库。 我使用Solr(快速)执行搜索,并使用JPA从数据库中检索Solr搜索中的每个结果。 JPA在数据库上运行WHERE IN
查询非常慢。
有没有办法让这个过程更快,或重构设计以提高性能?
我刚刚使用MySQL的全文搜索重构整个应用程序以使用Solr,现在性能更差。
注意:我需要立即对所有结果进行计算,因此我不能使用分页。
Java代码:
SolrDocumentList documentList = response.getResults();
Collection<String> listingIds = new ArrayList<>();
for(SolrDocument doc : documentList) {
String listingId = (String) doc.getFirstValue("ListingId");
listingIds.add(listingId);
}
Query query = em.createNamedQuery("getAllListingsWithId");
query.setParameter("listingIds", listingIds);
List<ListedItemDetail> listings = query.getResultList();
命名查询:
<query>Select listing from ListingSet listing where listing.listingId in :listingIds</query>
附加信息:
SHOW CREATE TABLE ListingSet
生成[缩短]:
CREATE TABLE `listingset` (
`LISTINGID` int(11) NOT NULL,
`STARTDATE` datetime DEFAULT NULL,
`STARTPRICE` decimal(10,2) DEFAULT NULL,
`TITLE` varchar(255) DEFAULT NULL,
PRIMARY KEY (`LISTINGID`),
KEY `FK_LISTINGSET_MEMBER_MEMBERID` (`MEMBER_MEMBERID`),
CONSTRAINT `FK_LISTINGSET_MEMBER_MEMBERID` FOREIGN KEY (`MEMBER_MEMBERID`) REFERENCES `member` (`MEMBERID`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1
调查生成的SQL
查看生成的SQL,JPA为单个JPA查询运行了大量SQL查询。 ListingSet表有7个链接到的表,并为每个表的每个表运行一个单独的SELECT查询(其中有1,000 - 10,000个)。 所以我的一个JPA查询被吹成了~7,000个查询!
以下是关于调试问题的个人想法:
打开mysql查询日志并检查JPA是否每次查询每个listingId都不访问MySQL。
mysql -uroot -pYOUR-PASSWORD -e“SET GLOBAL log_output ='FILE';设置GLOBAL general_log_file ='/ tmp / mysql.log'; SET GLOBAL general_log ='ON';” tail -f /tmp/mysql.log
检查性能是否由MySQL引起,在MySQL数据库中运行等效的SQL。
从ListingSet中选择listingId所在的列表(将你的真实listingId放在这里);
确保在ListingId列上有索引(可能很有可能索引已经存在)
由于您只读取了MySQL中的行,也许您可以为更多的slave设置Replicate,然后将您的ListingIds拆分为所有从属MySQL,然后合并结果。 http://dev.mysql.com/doc/refman/5.0/en/replication-howto.html
问题是由于我使用JPA引起的。 由于我的实体之间存在许多关系,因此单个查询分解为1,000-10,000个查询。
解决方案是在JPA中使用批处理来防止ORM n + 1查询问题。 批处理使JPA立即从相关表中请求所有相关行,而不是每个实体请求一次。 当查询返回许多结果时,此解决方案是合适的,并且被查询的实体具有许多关系。
确定JPA潜在问题的最简单方法是实现更精细的日志记录。 对于EclipseLink,将属性添加到persistence.xml
:
<property name="eclipselink.logging.level" value="FINEST"/>
请注意,在EclipseLink的默认设置下生成的日志记录仅显示查询的JPQL格式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.