I'm trying to make a simple servlet to display some data from my database using spring framework JdbcDaoSupport. Executing one single "SELECT"-sql command takes up about 25-35 seconds. And Im pretty new to spring and i don't get why this takes so long...
Here is my code: BeanBox.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
">
<!-- Data access related beans-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>Settings.properties</value>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.driverClassName}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.user}" />
<property name="password" value="${db.password}" />
<property name="initialSize" value="8" />
</bean>
<bean id="productAnalyticsDAO" class="productAnalyticsDAO">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
products.java (the actual servlet)
public class products extends HttpServlet {
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("start:" + System.nanoTime());
response.setContentType("text/html;charset=UTF-8");
ApplicationContext context = new ClassPathXmlApplicationContext("BeanBox.xml");
System.out.println("context created from xml:" + System.nanoTime());
productAnalyticsDAO productDAO = (productAnalyticsDAO) context.getBean("productAnalyticsDAO");
System.out.println("getbean for the DAO:" + System.nanoTime());
String interval = request.getParameterMap().isEmpty()? "today" : request.getParameter("t");
System.out.println("fetch time parameter from request:" + System.nanoTime());
try (PrintWriter out = response.getWriter()) {
/* TODO output your page here. You may use following sample code. */
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet products</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Product analytics : " + interval.toUpperCase() + "</h1>");
out.println("<a href=\"products?t=today\">Today</a>, ");
out.println("<a href=\"products?t=1D\">Yesterday</a>, ");
out.println("<a href=\"products?t=WEEKEND\">Weekend</a>, ");
out.println("<a href=\"products?t=1W\">1 Week</a>, ");
out.println("<a href=\"products?t=1M\">1 Month</a>, ");
out.println("<a href=\"products?t=3M\">3 Month</a>, ");
out.println("<a href=\"products?t=YTD\">Year To Date</a>, ");
out.println("<a href=\"products?t=1Y\">1 Year</a>, ");
out.println("<a href=\"products?t=3Y\">3 Year</a>");
out.println("<table>");
System.out.println("HTML print 1:" + System.nanoTime());
List sales = productDAO.getProducts(interval);
System.out.println("Fetched sqles list:" + System.nanoTime());
for (Iterator iterator = sales.iterator(); iterator.hasNext();) {
out.println("<tr>");
LinkedCaseInsensitiveMap next = (LinkedCaseInsensitiveMap) iterator.next();
out.println("<td>" + next.get("REFERENCE") + "</td>");
out.println("<td>" + next.get("NAME") + "</td>");
out.println("<td>" + next.get("UNITS") + "</td>");
out.println("</tr>");
}
System.out.println("Print data:" + System.nanoTime());
out.println("</table>");
out.println("</body>");
out.println("</html>");
}
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
productAnalyticsDAO.java (The Data access object)
public class productAnalyticsDAO extends JdbcDaoSupport {
public List<String[]> getProducts(String interval){
System.out.println("Entered getProducts:" + System.nanoTime());
String sql = "SELECT PRODUCTS.REFERENCE, "
+ "PRODUCTS.NAME, "
+ "PRODUCTS.CATEGORY, "
+ "SUM(TICKETLINES.UNITS) AS UNITS, "
+ "SUM(TICKETLINES.UNITS * TICKETLINES.PRICE) AS TOTAL "
+ "FROM RECEIPTS, "
+ "TICKETS, "
+ "TICKETLINES, "
+ "PRODUCTS "
+ "WHERE RECEIPTS.ID = TICKETS.ID "
+ "AND TICKETS.ID = TICKETLINES.TICKET "
+ "AND TICKETLINES.PRODUCT = PRODUCTS.ID ";
if(interval.equals("today")){
sql += "AND DATE(RECEIPTS.DATENEW)= CURDATE() ";
}
if(interval.equals("1D")){
sql += "AND DATE_SUB(CURDATE(),INTERVAL 1 DAY) <= DATE(RECEIPTS.DATENEW) ";
}
if(interval.equals("1W")){
sql += "AND DATE_SUB(CURDATE(),INTERVAL 1 WEEK) <= DATE(RECEIPTS.DATENEW) ";
}
if(interval.equals("WEEKEND")){
sql += "AND DATE_SUB(CURDATE(),INTERVAL 1 WEEK) <= DATE(RECEIPTS.DATENEW) ";
sql += "AND DAYOFWEEK(DATE(RECEIPTS.DATENEW))=1 OR DAYOFWEEK(DATE(RECEIPTS.DATENEW))=7 ";
}
if(interval.equals("1M")){
sql += "AND DATE_SUB(CURDATE(),INTERVAL 1 MONTH) <= DATE(RECEIPTS.DATENEW) ";
}
if(interval.equals("3M")){
sql += "AND DATE_SUB(CURDATE(),INTERVAL 3 MONTH) <= DATE(RECEIPTS.DATENEW) ";
}
if(interval.equals("YTD")){
sql += "AND YEAR(RECEIPTS.DATENEW)= YEAR(CURDATE()) <= DATE(RECEIPTS.DATENEW) ";
}
if(interval.equals("1Y")){
sql += "AND DATE_SUB(CURDATE(),INTERVAL 1 YEAR) <= DATE(RECEIPTS.DATENEW) ";
}
if(interval.equals("3Y")){
sql += "AND DATE_SUB(CURDATE(),INTERVAL 3 YEAR) <= DATE(RECEIPTS.DATENEW) ";
}
sql += "AND NOT PRODUCTS.CATEGORY = \"9286649c-00e1-428a-bd45-b47a1e0154b4\" " // filter out ophaal uren
+ "GROUP BY PRODUCTS.CATEGORY, PRODUCTS.NAME "
+ "ORDER BY PRODUCTS.NAME";
System.out.println("Builded SQL string:" + System.nanoTime());
List myBook = getJdbcTemplate().queryForList(sql);
System.out.println("Fetched data:" + System.nanoTime());
return myBook;
}
I'm using System.nanoTime() to calculate the arcs between different points:
So, why does the getJdbcTemplate().queryForList(sql)
takes so slow... The database is on localhost and executing the sql statement via phpMyAdmin goes much much quicker... Showing rows 0 - 31 (32 total, Query took 0.1411 seconds.)
Edit: Final SQL command executed is: SELECT PRODUCTS.REFERENCE, PRODUCTS.NAME, PRODUCTS.CATEGORY, SUM(TICKETLINES.UNITS) AS UNITS, SUM(TICKETLINES.UNITS * TICKETLINES.PRICE) AS TOTAL FROM RECEIPTS, TICKETS, TICKETLINES, PRODUCTS WHERE RECEIPTS.ID = TICKETS.ID AND TICKETS.ID = TICKETLINES.TICKET AND TICKETLINES.PRODUCT = PRODUCTS.ID AND DATE(RECEIPTS.DATENEW)= CURDATE() AND NOT PRODUCTS.CATEGORY = "9286649c-00e1-428a-bd45-b47a1e0154b4" GROUP BY PRODUCTS.CATEGORY, PRODUCTS.NAME ORDER BY PRODUCTS.NAME
Thank you, Robin
One possibility is the query formation which could be slowing down the result The query should be if this format
FROM RECEIPTS LEFT OUTER JOIN TICKETS ON RECEIPTS.ID = TICKETS.ID LEFT OUTER JOIN TICKETLINES ON TICKETS.ID = TICKETLINES.TICKET LEFT OUTER JOIN PRODUCTS ON TICKETLINES.PRODUCT = PRODUCTS.ID
You can also try indexing the columns which will make it run faster but use it after through evaluation
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.