【发布时间】:2012-12-01 04:21:37
【问题描述】:
我有一个由 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 查询以获取每个列表 ID(其中有 1,000 - 10,000 个)。所以我的一个 JPA 查询被炸成了大约 7,000 个查询!
【问题讨论】:
-
SQL 语法将是:`从 ListingSet 列表中选择列表,其中列表.listingId in (:listingIds)';鉴于 listingIds 是一个逗号列表。
-
JPA 处理这个问题。
<query>..</query>中的查询不是原始 SQL 查询,而是转换为 JPA 建议的形式。 -
我知道 JPA 可以做各种各样的事情,但我希望您的问题可以通过查看生成的 SQL 来回答。在其他情况下,您必须查阅手册。
-
我的问题不是对运行的查询感到困惑。我的问题是连接 Solr 和 MySQL 的典型方式是什么,这样性能不会很差。我已经看到 JPA 运行的查询,它是标准的 WHERE IN,带有逗号分隔的 id 列表。
-
好吧:看看发出的 SQL,或者只是添加括号并尝试。也许您甚至需要引用/取消引用?