我试图使用spring框架JdbcDaoSupport创建一个简单的servlet来显示数据库中的一些数据。执行一个" SELECT" -sql命令大约需要25-35秒。我是春天的新手,我不知道为什么这需要这么久......
这是我的代码: 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(实际的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(数据访问对象)
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;
}
我使用System.nanoTime()来计算不同点之间的弧线:
那么,为什么getJdbcTemplate().queryForList(sql)
需要这么慢......
数据库在localhost上,通过phpMyAdmin执行sql语句的速度要快得多...... Showing rows 0 - 31 (32 total, Query took 0.1411 seconds.)
编辑:执行的最终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 AND DATE(RECEIPTS.DATENEW)= CURDATE() AND NOT PRODUCTS.CATEGORY = "9286649c-00e1-428a-bd45-b47a1e0154b4" GROUP BY PRODUCTS.CATEGORY, PRODUCTS.NAME ORDER BY PRODUCTS.NAME
谢谢你, 罗宾
答案 0 :(得分:0)
一种可能性是查询形成可能会减慢结果 查询应该是这种格式
来自收据 LEFT OUTER JOIN TICKETS ON RECEIPTS.ID = TICKETS.ID LEFT OUTER JOIN TICKETLINES ON TICKETS.ID = TICKETLINES.TICKET 左外联产品 ON TICKETLINES.PRODUCT = PRODUCTS.ID
您还可以尝试indexing列,这样可以让它更快地运行,但在评估后使用它