TOP子句适用于@NamedQuery

时间:2012-04-26 12:17:02

标签: hibernate named-query show-sql

我已命名查询 @NamedQuery(name="CustomerMarket.findByMarketId", query="SELECT DISTINCT c.marketid FROM CustomerMarket c WHERE c.marketid LIKE :mask") 在我的CustomerMarket类定义中。

我想先获取350_000个结果的1_000个,所以我应用了setMaxResult:

Query market = session.getNamedQuery("CustomerMarket.findByMarketId");
market.setString("mask", getMask() + "%");
market.setMaxResults(1000);
List<Object> result = market.list()

执行此查询后,我检查了server.log并找到了此

select distinct customerma0_.marketid as col_0_0_ 
from   CUSTOMER_MARKET_S customerma0_ 
where  customerma0_.marketid like ?

我有正确的数据,首先是1_000条记录,但我想知道是否应用了TOP限制以及在哪里。

这个TOP子句是如何处理的?

  1. TOP应用于Hibernate使用的可调用语句,并且不会显示在日志
  2. 在收到DB的结果并在Java端过滤数据后应用TOP
  3. 或其他任何东西
  4. 我已经设置了persistance.xml和log4j.properties来显示几乎所有东西,但我认为没有问题,因为我有SQL脚本。

    修改: 我在两种情况下(使用和不使用setMaxResults)对性能进行了一些测量,并得到以下时间:

    long time = System.currentTimeMillis();
    market.list();
    LOGGER.info("time: " + (System.currentTimeMillis() - time) + "ms");
    

    在没有TOP的第一种情况下,我每次选择的平均时间消耗为1400ms。 在实施TOP的第二种情况下,我的平均时间消耗约为150ms。

    我还告诉我,这个TOP实现可能依赖于使用过的Hibernate方言(我们使用的是Sybase)。并且日志中显示的选择与发送到DB完全相同。 但是在这种情况下将350k结果从结果集(或者如何将结果存储在Hibernate会话中)转换为结构List而没有任何元数据需要这么长时间是正常的吗? 我可以想象在内部它被转换成类似的东西:

    **SQL generating process**
    **SQL setting parameters**
    ResultSet rs = executeQuery();
    List<Object[]> result = new ArrayList<Object[]>(rs.getFetchSize());
    int rowSize = rs.getMetaData().getColumnCount()
    while (rs.next) {
      Object[] row = new Object[rowSize];
      for (int i = 0; i < rowSize; i++) {
        row[i] = rs.getObject(i);
      }
    }
    

    这似乎并不那么复杂,为什么会出现这种时差。可能我很天真,因为Hibernate是一个具有很多功能的复杂框架。 :-D

1 个答案:

答案 0 :(得分:0)

似乎我的问题在于我用于我的应用程序的数据库。在链接www.petefreitag.com/item/59.cfm上,描述了用户如何限制其结果数量。如您所见,Sybase中只有一种选择分为两个单独的动作(SET + SELECT)。所以整个问题是没有记录第一个动作而第二个动作是。