有效地查找记录子集以及总计数

时间:2013-10-17 18:58:10

标签: sql oracle coldfusion

我在ColdFusion中编写一个函数,它返回与用户输入匹配的前几个记录,以及整个数据库中匹配记录的总数。该功能将用于提供自动完成功能,因此速度/效率是其最关注的问题。例如,如果函数接收输入"bl",则可能返回{sampleMatches:["blue", "blade", "blunt"], totalMatches:5000}

为了达到速度目的,我尝试在单个查询中执行此操作,最后得到的内容如下所示:

select record, count(*) over ()
from table
where criteria like :criteria
and rownum <= :desiredCount

此解决方案的问题是count(*) over ()始终返回:desiredCount的值。我看到了类似的问题here,但我的应用程序无权创建临时表。那么有一种方法可以在一个查询中解决我的问题吗?有没有更好的方法来解决它?谢谢!

2 个答案:

答案 0 :(得分:5)

我正在写这篇文章,所以你肯定要花时间,但我相信使用以下CTE

  • 只要求你写一次条件
  • 仅返回您指定的记录数量
  • 为每条记录添加了正确的总计数
  • 并且只评估一次

SQL声明

WITH q AS (
  SELECT record
  FROM   table
  WHERE  criteria like :criteria
)
SELECT q1.*, q2.*
FROM   q q1
       CROSS JOIN (
         SELECT COUNT(*) FROM q
       ) q2
WHERE  rownum <= :desiredCount

答案 1 :(得分:3)

嵌套子查询应该返回您想要的结果

select record, cnt
  from (select record, count(*) over () cnt
          from table
         where criteria like :criteria) 
 where rownum <= :desiredCount

然而,这将迫使Oracle完全处理查询以生成准确的count。如果您尝试执行自动完成,这似乎不太可能是您想要的,特别是当Oracle可能认为如果table只是{{1}而在:criteria上执行表扫描会更有效率因为那个谓词不够有选择性。你真的确定你需要一个完全准确的结果数量吗?你确定你的桌子足够小/你的系统足够快/你的谓词是否足够有选择性,这是你可以实际满足的要求?是否有可能返回更便宜(但不太准确)的行数估计?或者将b限制为更小的(例如100)并让UI显示“更多100%的结果”?