将 LIMITed SELECT 和总 COUNT 组合在一起?
Posted
技术标签:
【中文标题】将 LIMITed SELECT 和总 COUNT 组合在一起?【英文标题】:Combining a LIMITed SELECT and a total COUNT together? 【发布时间】:2014-07-25 22:38:26 【问题描述】:我有一个名为profile
的表,其中包含用户信息。我需要对此表进行过滤查询并获得:
-
与此查询匹配的行数。
仅前 5000 个匹配行的数据。
我正在寻找一种最佳方式来做到这一点。显然,至少需要进行一次扫描才能进行计数,但理想情况下,数据库可以在进行计数时获取顶部匹配项。
以下查询给了我正确的结果,但它看起来有点 hacky。我想知道它是否可以做得更好?
WITH total AS (
SELECT COUNT(*) AS total FROM profile
WHERE project_id = 1 and some_prop = 100)
SELECT total.total, full_name, other_prop
FROM profile
INNER JOIN total ON 1 = 1
WHERE project_id = 1 and some_prop = 100
ORDER BY full_name ASC
LIMIT 5000
有没有更有效的方法来做到这一点?
【问题讨论】:
鉴于您正在做的事情,我认为它没有什么特别的问题,但是您可以将“inner join total on 1 = 1”更改为“cross join total”,这更有意义,虽然我怀疑它会表现得更好。 基本上与此重复:***.com/questions/156114/…。但不确定 Redshift,它是过时和现代功能的奇怪组合。 您的窗口方法在 Redshift 上也是最快的(到目前为止)。 【参考方案1】:您正在扫描同一个表两次以应用过滤器。使用下面的内容,您只需在应用过滤器后扫描表格,然后在过滤后的表格上进行总计和列出。
with s as (
select *
from profile
where project_id = 1 and some_prop = 100
), t as (
select count(*) as total from s
)
select total, full_name, other_prop
from s cross join t
order by full_name asc
limit 5000
窗口函数版本
select
count(*) over() as total,
full_name,
other_prop
from profile
where project_id = 1 and some_prop = 100
order by full_name asc
limit 5000
【讨论】:
谢谢,我没想过这样做。这个执行计划实际上与我之前的查询相同。它可能已经达到预期效果了。 @AndySavage 测试窗口函数版本 window 方法在查询计划上看起来好多了。太好了。以上是关于将 LIMITed SELECT 和总 COUNT 组合在一起?的主要内容,如果未能解决你的问题,请参考以下文章
请问,如何用一条SQL查询出分页的数据和总记录数啊?MySQL的!不用存储
将 Microsoft Office Access 数据库引擎 2007 包含到 InstallShield Limited Edition 的安装程序中