我在MySQL中有一个名为Orders的表,其中包含订单的详细信息。
我有另一个表,称为OrderItems。

OrderItems包含以下字段:OrderID,ProductID,Qty

现在在Java中,我有一个名为Order的类,该类具有一个列表。

假设我要从数据库中获取所有订单,包括每个订单的OrderItems。但我想以最有效的方式做到这一点。

我当前的解决方案(我认为可能很慢)是:

遍历行的ResultSet并定义OrderDetails,每次遍历行时,我执行另一个PreparedStatement并遍历具有当前Order的OrderID的OrderItems。然后,将项目添加到列表中,然后转到下一个顺序。

但我可以想象,此过程将非常缓慢且需要大量资源。在仍被标准化的情况下,最有效的方法是什么(3NF)。

根据要求,我写了一个解决方案的例子

public List<Order> getAllOrders() throws SQLException{
    ArrayList<Order> list = new ArrayList<Order>(0);
    ResultSet x = qry("Select * from Orders");
    while(x.next()){
        Order r = new Order();
        //setOrderDetails
        r.setItems(getOrderItems(r));
    }
    return list;
}
public ArrayList<OrderItem> getOrderItems(Order r) throws SQLException {
    ArrayList<OrderItem> list = new ArrayList<OrderItem>(0);
    ResultSet x = qry("Select * from OrderItems where OrderID = "+r.getId()+";");
    while(x.next()){
        OrderItem  newItem = new OrderItem();
        newItem.setOrderId(r.getId());
        newItem.setProduct(null); //Uses some kind of inner join to get the product details
        newItem.setPrice(newItem.getProduct().getPrice());
        newItem.setQuantity(x.getInt(4));
    }
    return list;
}


好吧,我遵循了你们的建议...平均仍然需要20秒以上的时间。How it looks

日志:

Time took to connect: 3270ms
Start CustomerService: 38ms
Start ProductService: 1ms
Start OrderService: 2ms
Customer Size: 4
Qry All Customers: 149ms
Products Size: 420
Qry All Products: 391ms
Order already contains: ENALAPRILMALEAAT HCT 20/12,5MG ACTAVIS BV
Add Order(28 items) Took: 2350ms
Qry all orders(27 orders) took: 7929ms


这真的很难...有时可能要花费20秒。(要查询所有订单)

这是另一个仍需时30秒以仅qry 28个订单的时钟。(每个最多包含28件

连接时间:7117毫秒
启动客户服务:35ms
启动产品服务:1毫秒
Start OrderService:1毫秒
客户人数:4
Qry所有客户:126ms
产品尺寸:420
Qry所有产品:700ms
新增订单(6件)耗时:2117ms
Qry全部订单(28个订单):30150ms

最佳答案

我认为,您的数据(每周有4个新订单的600个产品)的数据并不庞大,以至于您现在需要进行性能优化。但是如果可以的话,如果您的代码如下所示,则可以对其进行优化(我只是稍微修改了一下代码):

public List<Order> getAllOrders() throws SQLException{
   ArrayList<Order> list = new ArrayList<Order>(0);
   PreparedStatement ps = connection.prepareStatement("Select * from OrderItems where OrderID = ?");        // (1)
   ResultSet x = qry("Select * from Orders");
   while(x.next()){
       Order r = new Order();
       //setOrderDetails
       r.setItems(getOrderItems(r, ps));
       list.add(r);
   }

   return list;
}

public ArrayList<OrderItem> getOrderItems(Order r, PreparedStatement ps) throws SQLException {
    ArrayList<OrderItem> list = new ArrayList<OrderItem>(0);
    ps.setString(1, r.getId());       // (2)
    ResultSet x = ps.executeQuery();  // (3)
    while(x.next()){
        OrderItem  newItem = new OrderItem();
        newItem.setOrderId(r.getId());
        newItem.setProduct(null); //Uses some kind of inner join to get the product details
        newItem.setPrice(newItem.getProduct().getPrice());
        newItem.setQuantity(x.getInt(4));
    }
    return list;
}


现在发生了什么变化?


现在,准备好的语句不在循环中,并且将被重用(请参阅更改(1))。与先前准备的查询相比,这将带来巨大的性能提升,因为查询将仅被解析一次。
在(2)中,将为当前订单设置参数。
在(3)中,将执行查询。

09-20 20:18