[英]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.