有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring MongoRepository转换POJO非常慢

问题说明

我的RESTAPI有一个很大的性能问题。 我在谷歌上找不到任何帮助,所以我在这里问我的问题

我可以针对缓慢的查询,但这不是因为查询本身,因为当我直接在Compass中运行它时,需要0毫秒

我认为问题在于Java,当它将查询结果转换为POJO时,如何改进它

项目设置和代码

波姆。xml

        <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.3.1.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com</groupId>
        <artifactId>myproject</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>myproject</name>
        <description>myproject API</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>com.newrelic.agent.java</groupId>
                <artifactId>newrelic-java</artifactId>
                <version>5.12.1</version>
                <scope>provided</scope>
                <type>zip</type>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-mongodb</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-rest</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-mail</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-oauth2-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-core</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.google.auth</groupId>
                <artifactId>google-auth-library-oauth2-http</artifactId>
                <version>0.16.1</version>
            </dependency>
            <dependency>
                <groupId>com.google.firebase</groupId>
                <artifactId>firebase-admin</artifactId>
                <version>6.9.0</version>
            </dependency>
            <dependency>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-annotations</artifactId>
                <version>1.5.14</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>4.1.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>4.1.2</version>
            </dependency>
    
            <dependency>
                <groupId>org.passay</groupId>
                <artifactId>passay</artifactId>
                <version>1.6.0</version>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <version>3.0.2</version>
                    <executions>
                        <execution>
                            <id>unpack-newrelic</id>
                            <phase>package</phase>
                            <goals>
                                <goal>unpack-dependencies</goal>
                            </goals>
                            <configuration>
                                <includeGroupIds>com.newrelic.agent.java</includeGroupIds>
                                <includeArtifactIds>newrelic-java</includeArtifactIds>
                                <overWriteReleases>false</overWriteReleases>
                                <overWriteSnapshots>false</overWriteSnapshots>
                                <overWriteIfNewer>true</overWriteIfNewer>
                                <outputDirectory>${project.basedir}</outputDirectory>
                                <destFileName>newrelic</destFileName>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
    </project>

项目。爪哇

    /*
     *  Copyright (C) 2020
     *  Produced by Wuidev
     */
    package com.myproject.api.model;
    
    import lombok.Data;
    import org.springframework.data.annotation.Id;
    
    @Data
    public class Item {
    
        @Id
        private String id;
    
    }

MenuChoice。爪哇

    /*
     *  Copyright (C) 2020
     *  Produced by Wuidev
     */
    package com.myproject.api.model;
    
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    import org.springframework.data.mongodb.core.index.Indexed;
    import org.springframework.data.mongodb.core.mapping.DBRef;
    
    import java.util.List;
    
    @Data
    @EqualsAndHashCode(callSuper = false)
    public class MenuChoice extends Item {
    
    //    private String customerId;
        @DBRef
        private Customer customer;
    
        @Indexed
        @DBRef
        private Menu menu;
    //    private String menuId;
        private List<MenuItemChoice> choices;
        private String comment;
        private String timeSlot;
    
    }

Menuchoicepository。爪哇

package com.myproject.api.dao;

import com.myproject.api.model.Menu;
import com.myproject.api.model.MenuChoice;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;

/**
 * The interface Menu choice repository.
 */
public interface MenuChoiceRepository extends MongoRepository<MenuChoice, String> {

    
    /**
     * Find all by menu list.
     *
     * @param menu the menu
     * @return the list
     */
    List<MenuChoice> findAllByMenu(Menu menu);

}

DefaultMenuChoiceService


@Component
public class DefaultMenuChoiceService extends AbstractDefaultItemService<MenuChoice> implements MenuChoiceService {

    @Override
    public List<MenuChoice> getChoicesForMenu(final Menu m) {
        final long startTime = System.currentTimeMillis();
        if(m == null) {
            return Collections.emptyList();
        }
        final List<MenuChoice> choices = menuChoiceRepository.findAllByMenu(m);
//        final List<MenuChoice> choices = menuChoiceRepository.findAllByMenu_Id(m.getId());
        LOG.info("getChoicesForMenu total = {}", (System.currentTimeMillis() - startTime));
        return choices;
    }


}

结果

我已将mongoTemplate日志记录级别设置为DEBUG,以下是查询:

find using query: { "menu" : { "$java" : { "$ref" : "menu", "$id" : "foo" } } } fields: Document{{}} for class: class com.myproject.api.model.MenuChoice in collection: menuChoice

本地环境

文件总数:22

返回的MenuChoice文档数:1

getChoicesForMenu total = 561

生产环境

菜单文档总数:341

返回的MenuChoice文档数:27

getChoicesForMenu total = 27149

尝试过的解决方案

  1. 在MenuChoice集合的菜单字段上添加索引
  2. 升级Spring启动版本
  3. 我试过一次又一次地关掉它

但一切都没有改变


共 (1) 个答案

  1. # 1 楼答案

    我怀疑你的问题在于@DBRef。我从未使用过它,但根据文档,您的查询也会从不同的集合中检索客户菜单(即每个菜单有+2个查询,不确定SpringJPA如何处理,但由于MongoDB是NO-SQL,我怀疑这些查询是不同的)

    更多详情请访问MongoDB - is DBREF necessary?

    Compass中的查询速度如此之快的原因是,这些额外的查询不会被执行,而SpringJPA也会执行额外的查询,因此您有一个完整的POJO

    在改进方面,您有以下选择:

    1. 对菜单和客户使用外键,并根据需要检索它们
    2. 将客户和菜单移到同一个集合中,因此无需参考 <> LI>如果您希望使用引用,那么MunGDB是不适合的,考虑使用关系DBS,如PrGRE、MySQL、MSSQL、Oracle SQL。李>