簡體   English   中英

提高Solr和MySQL對的性能(使用JPA通過“WHERE IN”連接)

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM