我在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,但我的应用程序无权创建临时表。那么有一种方法可以在一个查询中解决我的问题吗?有没有更好的方法来解决它?谢谢!
答案 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%的结果”?