- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
你能帮我理解这些语句之间性能下降的原因吗?
对我来说,在 D & E 的情况下,他首先将地址加入所有订阅者,最后应用 Offset & Limit。他到底为什么要这么做?
我是否遗漏了有关 Subselects 和 Offset 如何协同工作的信息?他不应该先找到正确的偏移量然后开始执行子选择吗?
user_id 和 address_id 是主键
选择 A:15 毫秒(确定):选择前 200 个订阅者
SELECT s.user_id
FROM subscribers s
ORDER BY s.user_id
OFFSET 0 LIMIT 200
选择 B:45 毫秒(确定):选择最后 200 个订阅者
SELECT s.user_id
FROM subscribers s
ORDER BY s.user_id
OFFSET 100000 LIMIT 200
选择 C:15 毫秒(确定):选择前 200 个订阅者以及第一个可用地址
SELECT s.user_id,
(SELECT address_id FROM address a WHERE a.user_id = s.user_id ORDER BY address_id OFFSET 0 LIMIT 1) AS a_id
FROM subscribers s
ORDER BY s.user_id
OFFSET 0 LIMIT 200
选择 D:500 毫秒(不正确):选择最后 200 个订阅者以及第一个可用地址
SELECT s.user_id,
(SELECT address_id FROM address a WHERE a.user_id = s.user_id ORDER BY address_id OFFSET 0 LIMIT 1) AS a_id
FROM subscribers s
ORDER BY s.user_id
OFFSET 100000 LIMIT 200
选择 E:1000 毫秒(甚至更糟):选择最后 200 个订阅者以及前 2 个可用地址
SELECT s.user_id,
(SELECT address_id FROM address a WHERE a.user_id = s.user_id ORDER BY address_id OFFSET 0 LIMIT 1) AS a_id_1,
(SELECT address_id FROM address a WHERE a.user_id = s.user_id ORDER BY address_id OFFSET 1 LIMIT 2) AS a_id_2
FROM subscribers s
ORDER BY s.user_id
OFFSET 100000 LIMIT 200
选择 F:15 毫秒(不错):选择最后 200 个订阅者以及前 2 个可用地址,没有偏移量,而是 WHERE s.user_id > 100385
SELECT s.user_id,
(SELECT address_id FROM address a WHERE a.user_id = s.user_id ORDER BY address_id OFFSET 0 LIMIT 1) AS a_id_1,
(SELECT address_id FROM address a WHERE a.user_id = s.user_id ORDER BY address_id OFFSET 1 LIMIT 2) AS a_id_2
FROM subscribers s
WHERE s.user_id > 100385 --same as OFFSET 100000 in my data
ORDER BY s.user_id
LIMIT 200
E 的执行计划:
'Limit (cost=1677635.30..1677635.80 rows=200 width=4) (actual time=2251.503..2251.816 rows=200 loops=1)'
' Output: s.user_id, ((SubPlan 1)), ((SubPlan 2))'
' Buffers: shared hit=607074'
' -> Sort (cost=1677385.30..1677636.08 rows=100312 width=4) (actual time=2146.867..2200.704 rows=100200 loops=1)'
' Output: s.user_id, ((SubPlan 1)), ((SubPlan 2))'
' Sort Key: s.user_id'
' Sort Method: quicksort Memory: 7775kB'
' Buffers: shared hit=607074'
' -> Seq Scan on public.pcv_subscriber s (cost=0.00..1669052.31 rows=100312 width=4) (actual time=0.040..2046.926 rows=100312 loops=1)'
' Output: s.user_id, (SubPlan 1), (SubPlan 2)'
' Buffers: shared hit=607074'
' SubPlan 1'
' -> Limit (cost=8.29..8.29 rows=1 width=4) (actual time=0.008..0.008 rows=1 loops=100312)'
' Output: ua.user_address_id'
' Buffers: shared hit=301458'
' -> Sort (cost=8.29..8.29 rows=1 width=4) (actual time=0.007..0.007 rows=1 loops=100312)'
' Output: ua.user_address_id'
' Sort Key: ua.user_address_id'
' Sort Method: quicksort Memory: 25kB'
' Buffers: shared hit=301458'
' -> Index Scan using ix_pcv_user_address_user_id on public.pcv_user_address ua (cost=0.00..8.28 rows=1 width=4) (actual time=0.003..0.004 rows=1 loops=100312)'
' Output: ua.user_address_id'
' Index Cond: (ua.user_id = $0)'
' Buffers: shared hit=301458'
' SubPlan 2'
' -> Limit (cost=8.29..8.29 rows=1 width=4) (actual time=0.009..0.009 rows=0 loops=100312)'
' Output: ua.user_address_id'
' Buffers: shared hit=301458'
' -> Sort (cost=8.29..8.29 rows=1 width=4) (actual time=0.006..0.007 rows=1 loops=100312)'
' Output: ua.user_address_id'
' Sort Key: ua.user_address_id'
' Sort Method: quicksort Memory: 25kB'
' Buffers: shared hit=301458'
' -> Index Scan using ix_pcv_user_address_user_id on public.pcv_user_address ua (cost=0.00..8.28 rows=1 width=4) (actual time=0.003..0.003 rows=1 loops=100312)'
' Output: ua.user_address_id'
' Index Cond: (ua.user_id = $0)'
' Buffers: shared hit=301458'
'Total runtime: 2251.968 ms'
免责声明:这是一个更大、更复杂的语句的精简示例,它使 GUI 表能够对具有跨多个表的大量额外累积数据的订阅者进行排序/分页/过滤。所以我知道这个例子可以用更好的方式来完成。因此,请帮助我理解为什么此解决方案如此缓慢或最多建议进行最小的更改。
更新 1:
这是使用 Postgres 9.0.3 制作的
更新 2:
目前我能想到的最好的解决方案似乎是这个愚蠢的声明:
选择 G:73ms(OKish)
SELECT s.user_id,
(SELECT address_id FROM address a WHERE a.user_id = s.user_id ORDER BY address_id OFFSET 0 LIMIT 1) AS a_id_1,
(SELECT address_id FROM address a WHERE a.user_id = s.user_id ORDER BY address_id OFFSET 1 LIMIT 2) AS a_id_2
FROM subscribers s
WHERE s.user_id >= (SELECT user_id from subscribers ORDER BY user_id OFFSET 100000 LIMIT 1)
ORDER BY s.user_id
LIMIT 200
更新 3:
David 迄今为止的最佳选择。 (与 G 性能相同但更直观)
选择 H:73ms(OKish)
SELECT s2.user_id,
(SELECT address_id FROM address a WHERE a.user_id = s2.user_id ORDER BY address_id OFFSET 0 LIMIT 1) AS a_id
FROM (SELECT s.user_id
FROM subscribers s
ORDER BY s.user_id
OFFSET 100000 LIMIT 200) s2
H 的执行计划:
这就是我最初对 E 的想象。
最佳答案
我认为即使对于您未包含在最终数据集中的 100000 行,也会执行 SELECT 子句中表达的连接。
这个怎么样:
SELECT s2.user_id,
(SELECT address_id FROM address a WHERE a.user_id = s2.user_id ORDER BY address_id OFFSET 0 LIMIT 1) AS a_id
FROM (select *
from subscribers s
ORDER BY s.user_id
OFFSET 100000 LIMIT 200) s2
做不到这一点,尝试一个通用的表表达式:
With s2 as (
select *
from subscribers s
ORDER BY s.user_id
OFFSET 100000 LIMIT 200)
SELECT s2.user_id,
(SELECT address_id FROM address a WHERE a.user_id = s2.user_id ORDER BY address_id OFFSET 0 LIMIT 1) AS a_id
FROM s2
关于performance - Postgres : Why is the performance so bad on subselects with Offset/Limit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29307991/
好吧,我对我的页面发生的事情有点困惑。我在底部有页码, table 上摆满了 23 种不同的元素。 每个页面应一次显示 5 个项目。我显示的页面发送了一个带有 pagenumber = 不管怎样的 g
几周前我开始学习 Ada。我知道 limited 在某些情况下声明了一个有限类型,不允许复制对象 来自 Ada Reference Manual 2012 7.5 1/2 A limited type
我想按 DESC 选择日期并限制为最后 3 个,然后我需要基本上翻转最后 3 个结果,以便它们按 ASC 排序 任何帮助将不胜感激,我正在使用 postgresql 最佳答案 SELECT * FRO
SELECT * FROM mm_tfs WHERE product_slug LIKE '%football%' AND schoolid = '8' AND category_id ='2
SELECT * FROM mm_tfs WHERE product_slug LIKE '%football%' AND schoolid = '8' AND category_id ='2
我正在尝试访问按“日期”键排序的表中恒定数量的最新文档。请注意,不幸的是,日期是被实现的(不是由我......),使得该值设置为字符串,例如“2014-01-14”,或者有时“2014-01-14 2
我目前正在使用具有限制 cpu、限制内存以及保留 cpu 和内存的 Docker Swarm。 完成测试后,我想删除这些配置。我找不到任何有关如何删除这些的文章。 是否有办法通过更新来删除这些设置而不
我目前正在使用具有限制 cpu、限制内存以及保留 cpu 和内存的 Docker Swarm。 完成测试后,我想删除这些配置。我找不到任何有关如何删除这些的文章。 是否有办法通过更新来删除这些设置而不
我必须对我的数据应用分页。我通过复杂的连接查询获取数据,没有任何子查询,只有简单的连接。 假设这个查询[这是一个非常简单的查询,我有一个比这个复杂的查询] SELECT states.state
我经常制作条形图,并将条形图的值额外包含为注释 (geom_text)。通常,我更喜欢这些值右对齐(与将标签放在条形顶部相反)。在绘制多面条形图时,我将这些值放在每个组中的最大值(我之前计算过)加上我
delivery-limit 和 x-delivery-limit 有什么区别? 当我将 x-delivery-limit 设置为 RabbitMQ 队列参数时,我可以看到它限制了我的消息重新排队尝试
delivery-limit 和 x-delivery-limit 有什么区别? 当我将 x-delivery-limit 设置为 RabbitMQ 队列参数时,我可以看到它限制了我的消息重新排队尝试
我正在使用 PostgreSQL 9.3。这应该在具有 100,000 多行的任何表上重现。 EXPLAIN ANALYZE 显示使用 LIMIT 2 扫描了更多行,但我不明白为什么。 限制 1: E
我正在尝试找出是否可以在 PHP 中全局设置和取消设置 MySQL 结果的默认限制。 一些可能看起来像的伪代码: $pdo->prepare('SELECT * FROM example'); $pd
我有下面的代码片段表 在这里我必须对投票前 3 个值求和。 假设 product_id 3030 vote 列的总和为 8.1 和 3671 总和 是 5.2 在这里,我必须获得前 3 个 produ
我正在使用全文搜索来提取行。 我根据分数 (ORDER BY SCORE) 对行进行排序,然后在前 20 行 (LIMIT 20) 中,我想对结果集进行兰德 (RAND)。 因此,对于任何特定的搜索词
帮助创建搜索条件 SELECT * FROM mlt_adr_city WHERE name LIKE "Text%" AND region_id = 59 AND id <> 0 IF (name
MySQL 查询示例: SELECT message_id, message_text FROM messages LIMIT 0 , 30 我得到的这个提示是错误的: HIN
我注意到如果我将查询限制为 1 个而不是 5 个,速度会急剧下降。 SELECT he. * FROM homematic_events he WHERE he.homematic_devices_i
我需要从我的表中获取最后一个 ID,以便我可以在另一个函数中使用它我在我的存储库中创建了这个函数,但我没有工作,它显示了一个错误: [Syntax Error] line 0, col 60: Err
我是一名优秀的程序员,十分优秀!