【问题标题】:Counting rows before proceeding to actual searching在进行实际搜索之前计算行数
【发布时间】:2012-07-23 11:39:40
【问题描述】:

假设一个 Web 应用程序(Java、Spring、Hibernate 和 Sybase 作为 DB)具有多个(例如 5 个)不同的搜索屏幕,我想首先计算基于用户条件的搜索结果是否超过限制,例如 1000 行.即使用户提供了合理的过滤器和标准,也可能会出现超过 1000 个的巨大结果。

推荐这样做:

  1. 在此处从表 --clauses 等中选择 count(*)
  2. 如果 > 1000,则不进行实际搜索,返回并显示限制错误(告诉用户细化搜索)
  3. else if

或者有更好的解决方案来处理这个问题吗?

如果这是要走的路,我的后续问题是,我们如何避免重复 sql 查询?因为我理解这样做,所以需要我声明相同的搜索 sql,除了 select 子句将只包含 count(*)。

更新

另外,我想避免两件事: 1.从执行实际的sql处理 2. 通过 ORM 加载/映射域对象(在这种情况下为 Hibernate) * 当我检测到计数 > 1000 时,避免使用 1 和 2。

【问题讨论】:

  • 你可能不会避免 (1) 你什么时候先 COUNT。您唯一要避免的是将结果从数据库发送回。对(2)的猜测是,如果你想使用 ORM,除非你想有两个查询,否则没有办法解决这个问题。
  • 在某些情况下,是的。检索行和计数会产生一些额外的 I/O 开销,但是如果没有达到限制的所有内容,查询就无法知道计数。

标签: java sql search web-search


【解决方案1】:

我根本不会运行COUNT(*),只需使用LIMIT 1001 运行查询。您可能在计数中生成完全相同的结果集(即,要执行 COUNT,您必须生成结果集),并且下一次命中将来自缓存,或者最坏的情况是您必须重新计算。你只是做了两次同样的工作

【讨论】:

  • 我明白了,有一段时间,我认为执行 COUNT 版本并不像执行实际 sql 那样昂贵...
  • 它可能会为您节省一些磁盘 I/O,但您也需要两次访问数据库。我没有任何明确的统计数据可供参考,但根据我的经验,这不太可能成为大瓶颈
  • 好的,select top 1000 * from table 会和limit一样吗?我忘了提到我们正在使用 Sybase。
【解决方案2】:

我们的申请也遵循相同的程序。是的,唯一的区别是在 SQL 中放置 count(1) 而不是 *。

但是,您可能需要了解,有时计数查询会花费更多时间然后获取结果子集。

【讨论】:

    【解决方案3】:

    根据您从行集中检索行的方式,您可以简单地过滤该级别的结果。

    int rowIndex = 0;
    while (rs.hasNext() && rowIndex < 1000) {
        // ... Extract results
        rowIndex++;
    }
    

    您可能希望警告用户结果集已被修剪;)

    【讨论】:

    • 感谢您的评论,但是,我想避免两件事:执行实际查询和加载/映射到我们的域对象(orm 为我们做的),这可能会占用堆中的大量空间虽然
    • 别担心,只是一个疯狂的想法;)
    猜你喜欢
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多