【问题标题】:spring mvc - ajax running slow +500ms for each callspring mvc - 每次调用的ajax运行缓慢+ 500ms
【发布时间】:2011-07-11 02:48:34
【问题描述】:

我们正在开发一个 Spring mvc 项目,但我们的 ajax 调用存在一些性能问题。每次调用至少需要 500 毫秒 :(。 以前有人遇到过这个问题吗?有没有很好的方法来分析这个问题?

我们利用:

  • spring mvc
  • 弹簧安全
  • 休眠 3.6.1
  • tomcat 7
  • jquery 1.4.4

使用 spring 洞察分析器后,我们发现这是问题所在:

    try {
        HibernateTemplate ht = new HibernateTemplate(sf);
        List<Route> r = ht.findByNamedParam("select r from Route r inner join r.carPoolers as carPooler where (( r.owner.id  = :userid ) or ( carPooler.user.id = :userid )) AND r.id =:routeID", new String[]{"userid", "routeID"} , new Object[]{ u.getId() , id});
        if (r.size() == 1) {
            return r.get(0);
        } else {
            return null;
        }
    } catch (DataAccessException ex) {
        LogFactory.getLog(RouteRepository.class).fatal(ex);
        return null;
    }

这个查询至少需要 460ms ...

SELECT ROUTE0_.ID AS ID4_, ROUTE0_.ARRIVALTIME AS ARRIVALT2_4_, 
    ROUTE0_.CAR_ID AS CAR13_4_, ROUTE0_.DATE AS DATE4_, 
    ROUTE0_.DAYOFWEEK AS DAYOFWEEK4_, ROUTE0_.DEPARTURETIME AS 
    DEPARTUR5_4_, ROUTE0_.ENDDATE AS ENDDATE4_, ROUTE0_.MESSAGEID 
    AS MESSAGEID4_, ROUTE0_.OPENSEATS AS OPENSEATS4_, 
    ROUTE0_.OWNER_ID AS OWNER14_4_, ROUTE0_.ROUTECACHE_ID AS 
    ROUTECACHE11_4_, ROUTE0_.ROUTEOPTIMIZED AS ROUTEOPT9_4_, 
    ROUTE0_.START_ID AS START12_4_, ROUTE0_.STOP_ID AS STOP10_4_ 
FROM ROUTE ROUTE0_ INNER JOIN CARPOOLER CARPOOLERS1_ ON 
    ROUTE0_.ID=CARPOOLERS1_.ROUTEID 
WHERE (route0_.owner_id=? or carpoolers1_.user_id=?) and route0_.id=?

SELECT CAR0_.ID AS ID5_3_, CAR0_.BRAND_ID AS BRAND8_5_3_, CAR0_.CARNAME 
    AS CARNAME5_3_, CAR0_.CARTYPE AS CARTYPE5_3_, CAR0_.IMAGEURL AS 
    IMAGEURL5_3_, CAR0_.PRICEKM AS PRICEKM5_3_, CAR0_.SEATS AS 
    SEATS5_3_, CAR0_.USER_ID AS USER7_5_3_, BRAND1_.ID AS ID6_0_, 
    BRAND1_.BRANDNAME AS BRANDNAME6_0_, USER2_.ID AS ID0_1_, 
    USER2_.EMAIL AS EMAIL0_1_, USER2_.FACEBOOKID AS FACEBOOKID0_1_, 
    USER2_.FIRSTNAME AS FIRSTNAME0_1_, USER2_.GENDER AS GENDER0_1_, 
    USER2_.IMAGEURL AS IMAGEURL0_1_, USER2_.LANGUAGE_ID AS 
    LANGUAGE12_0_1_, USER2_.LASTNAME AS LASTNAME0_1_, 
    USER2_.MOBILEPHONE AS MOBILEPH8_0_1_, USER2_.PASSWORD AS 
    PASSWORD0_1_, USER2_.SMOKER AS SMOKER0_1_, USER2_.TELEPHONE AS 
    TELEPHONE0_1_, LANGUAGE3_.ID AS ID9_2_, LANGUAGE3_.LANGUAGE AS 
    LANGUAGE9_2_, LANGUAGE3_.LANGUAGECODE AS LANGUAGE3_9_2_ 
FROM CAR CAR0_ LEFT OUTER JOIN BRAND BRAND1_ ON 
    CAR0_.BRAND_ID=BRAND1_.ID LEFT OUTER JOIN USER USER2_ ON 
    CAR0_.USER_ID=USER2_.ID LEFT OUTER JOIN LANGUAGE LANGUAGE3_ ON 
    USER2_.LANGUAGE_ID=LANGUAGE3_.ID 
WHERE car0_.id=?

SELECT USER0_.ID AS ID0_1_, USER0_.EMAIL AS EMAIL0_1_, 
    USER0_.FACEBOOKID AS FACEBOOKID0_1_, USER0_.FIRSTNAME AS 
    FIRSTNAME0_1_, USER0_.GENDER AS GENDER0_1_, USER0_.IMAGEURL AS 
    IMAGEURL0_1_, USER0_.LANGUAGE_ID AS LANGUAGE12_0_1_, 
    USER0_.LASTNAME AS LASTNAME0_1_, USER0_.MOBILEPHONE AS 
    MOBILEPH8_0_1_, USER0_.PASSWORD AS PASSWORD0_1_, USER0_.SMOKER 
    AS SMOKER0_1_, USER0_.TELEPHONE AS TELEPHONE0_1_, LANGUAGE1_.ID 
    AS ID9_0_, LANGUAGE1_.LANGUAGE AS LANGUAGE9_0_, 
    LANGUAGE1_.LANGUAGECODE AS LANGUAGE3_9_0_ 
FROM USER USER0_ LEFT OUTER JOIN LANGUAGE LANGUAGE1_ ON 
    USER0_.LANGUAGE_ID=LANGUAGE1_.ID 
WHERE user0_.id=?

SELECT ROUTECACHE0_.ID AS ID7_2_, ROUTECACHE0_.AANTALM AS AANTALM7_2_, 
    ROUTECACHE0_.AANTALMIN AS AANTALMIN7_2_, ROUTECACHE0_.ACTIVE AS 
    ACTIVE7_2_, ROUTECACHE0_.JSON AS JSON7_2_, 
    ROUTECACHE0_.LOCATIONS AS LOCATIONS7_2_, 
    ROUTECACHE0_.LOCATIONSOPTIMIZED AS LOCATION7_7_2_, 
    ROUTECACHE0_.ROUTEOPTIMIZED AS ROUTEOPT8_7_2_, 
    ROUTECACHE0_.START_ID AS START10_7_2_, ROUTECACHE0_.STOP_ID AS 
    STOP9_7_2_, LOCATION1_.ID AS ID2_0_, LOCATION1_.LANG AS 
    LANG2_0_, LOCATION1_.LAT AS LAT2_0_, LOCATION1_.NUMBER AS 
    NUMBER2_0_, LOCATION1_.STREET AS STREET2_0_, LOCATION1_.ZIPCODE 
    AS ZIPCODE2_0_, LOCATION2_.ID AS ID2_1_, LOCATION2_.LANG AS 
    LANG2_1_, LOCATION2_.LAT AS LAT2_1_, LOCATION2_.NUMBER AS 
    NUMBER2_1_, LOCATION2_.STREET AS STREET2_1_, LOCATION2_.ZIPCODE 
    AS ZIPCODE2_1_ 
FROM ROUTECACHE ROUTECACHE0_ LEFT OUTER JOIN LOCATION LOCATION1_ ON 
    ROUTECACHE0_.START_ID=LOCATION1_.ID LEFT OUTER JOIN LOCATION 
    LOCATION2_ ON ROUTECACHE0_.STOP_ID=LOCATION2_.ID 
WHERE routecache0_.id=?

 SELECT ROUTECACHE0_.ROUTECACHESPUNTENTUSSEN_ID AS ROUTECAC1_1_, 
    ROUTECACHE0_.ROUTECACHETUSSENPUNTEN_ID AS ROUTECAC2_1_, 
    LOCATION1_.ID AS ID2_0_, LOCATION1_.LANG AS LANG2_0_, 
    LOCATION1_.LAT AS LAT2_0_, LOCATION1_.NUMBER AS NUMBER2_0_, 
    LOCATION1_.STREET AS STREET2_0_, LOCATION1_.ZIPCODE AS 
    ZIPCODE2_0_ 
FROM ROUTECACHE_LOCATION_PUNTEN ROUTECACHE0_ LEFT OUTER JOIN LOCATION 
    LOCATION1_ ON 
    ROUTECACHE0_.ROUTECACHETUSSENPUNTEN_ID=LOCATION1_.ID 
WHERE routecache0_.routecachesPuntenTussen_id=?

 SELECT CARPOOLERS0_.ROUTEID AS ROUTEID5_, CARPOOLERS0_.ID AS ID5_, 
    CARPOOLERS0_.ID AS ID3_4_, CARPOOLERS0_.APPROVED AS 
    APPROVED3_4_, CARPOOLERS0_.ONETIME AS ONETIME3_4_, 
    CARPOOLERS0_.ROUTEID AS ROUTEID3_4_, CARPOOLERS0_.START_ID AS 
    START5_3_4_, CARPOOLERS0_.STOP_ID AS STOP7_3_4_, 
    CARPOOLERS0_.USER_ID AS USER6_3_4_, LOCATION1_.ID AS ID2_0_, 
    LOCATION1_.LANG AS LANG2_0_, LOCATION1_.LAT AS LAT2_0_, 
    LOCATION1_.NUMBER AS NUMBER2_0_, LOCATION1_.STREET AS 
    STREET2_0_, LOCATION1_.ZIPCODE AS ZIPCODE2_0_, LOCATION2_.ID AS 
    ID2_1_, LOCATION2_.LANG AS LANG2_1_, LOCATION2_.LAT AS LAT2_1_, 
    LOCATION2_.NUMBER AS NUMBER2_1_, LOCATION2_.STREET AS 
    STREET2_1_, LOCATION2_.ZIPCODE AS ZIPCODE2_1_, USER3_.ID AS 
    ID0_2_, USER3_.EMAIL AS EMAIL0_2_, USER3_.FACEBOOKID AS 
    FACEBOOKID0_2_, USER3_.FIRSTNAME AS FIRSTNAME0_2_, 
    USER3_.GENDER AS GENDER0_2_, USER3_.IMAGEURL AS IMAGEURL0_2_, 
    USER3_.LANGUAGE_ID AS LANGUAGE12_0_2_, USER3_.LASTNAME AS 
    LASTNAME0_2_, USER3_.MOBILEPHONE AS MOBILEPH8_0_2_, 
    USER3_.PASSWORD AS PASSWORD0_2_, USER3_.SMOKER AS SMOKER0_2_, 
    USER3_.TELEPHONE AS TELEPHONE0_2_, LANGUAGE4_.ID AS ID9_3_, 
    LANGUAGE4_.LANGUAGE AS LANGUAGE9_3_, LANGUAGE4_.LANGUAGECODE AS 
    LANGUAGE3_9_3_ 
FROM CARPOOLER CARPOOLERS0_ LEFT OUTER JOIN LOCATION LOCATION1_ ON 
    CARPOOLERS0_.START_ID=LOCATION1_.ID LEFT OUTER JOIN LOCATION 
    LOCATION2_ ON CARPOOLERS0_.STOP_ID=LOCATION2_.ID LEFT OUTER 
    JOIN USER USER3_ ON CARPOOLERS0_.USER_ID=USER3_.ID LEFT OUTER 
    JOIN LANGUAGE LANGUAGE4_ ON USER3_.LANGUAGE_ID=LANGUAGE4_.ID 
WHERE carpoolers0_.RouteId=?

, 提前联系

【问题讨论】:

  • 尝试找出这些查询的执行计划。也许您必须在某些加入/搜索的字段上创建一些索引。

标签: jquery sql hibernate spring-mvc


【解决方案1】:

请使用 Fiddler2

http://www.fiddler2.com/fiddler2/

您将能够查看请求/响应的时间戳以及查看瓶颈是在服务器还是客户端上的天气。 您可以通过在提琴手中的请求上单击鼠标右键来完成。

希望对你有帮助。

【讨论】:

    【解决方案2】:

    试试 Spring Insight。这是一个演示:

    http://www.youtube.com/watch?v=P_EskssNDU8

    这里有一些 docco:

    http://static.springsource.com/projects/tc-server/6.0/devedition/cinintro.html

    如果您使用STS,将其连接到您的 web 应用程序相当简单,它会向您显示端到端性能以及您遇到的任何瓶颈。

    有一篇非常好的博文,附有截图here

    【讨论】:

      【解决方案3】:

      根据您的帖子,听起来 SQL 查询是瓶颈(500 毫秒中的 460 毫秒)。我建议您尝试以下几件事:

      • 尝试更改 Hibernate 会话刷新模式。简而言之,默认情况下,无论何时执行查询,Hibernate 都必须遍历 Session 中的每个对象,以确定在执行查询之前是否需要将任何内容刷新到数据库中。根据会话中有多少内容,此过程可能需要比实际查询更长的时间来执行!以下是一些链接,其中包含有关更改刷新模式的更多信息。

      https://forums.hibernate.org/viewtopic.php?p=2263250&sid=3c1db460d6d28155799cf95f76730606 http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/FlushMode.html

      • 尝试先检查路由 ID。这可能会更快,具体取决于您使用的数据库
      • 通过分析工具运行 SQL。所有主要的数据库都有它们。配置文件工具会告诉您查询的哪一部分是最昂贵的,甚至可以告诉您索引可以显着缩短查询时间的地方。

      【讨论】:

        猜你喜欢
        • 2020-02-02
        • 1970-01-01
        • 1970-01-01
        • 2018-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多