每个不同的值我有一个包含队列项它们是周期性地(500毫秒)的表以分批的10获取2行用于
select * from tbl_queue order by prio asc;
----------------------------
client_id |object_key |prio
----------------------------
1 |4711 | 10
1 |2831 | 10
1 |1912 | 10
1 |1913 | 10
1 |1914 | 10
1 |1915 | 10
1 |1922 | 10
1 |1933 | 10
1 |1944 | 10
1 |1955 | 10
1 |1966 | 10
2 |7861 | 10
2 |1234 | 10
3 |5463 | 10
3 |5464 | 10
4 |7341 | 10
4 |7342 | 10
5 |9425 | 10
5 |9426 | 10
5 |9427 | 10
工作关闭每次我从表中我限制选择我想工作的金额:
select * from tbl_queue order by prio asc limit 10;
client_id |object_key |prio
----------------------------
1 |4711 | 10
1 |2831 | 10
1 |1912 | 10
1 |1913 | 10
1 |1914 | 10
1 |1915 | 10
1 |1922 | 10
1 |1933 | 10
1 |1944 | 10
1 |1955 | 10
不过,我想平等地对待每一个客户,所以我期望的结果を可以是:
----------------------------
client_id |object_key |prio
----------------------------
1 |1913 | 10
1 |1966 | 10
2 |7861 | 10
2 |1234 | 10
3 |5463 | 10
3 |5464 | 10
4 |7341 | 10
4 |7342 | 10
5 |9425 | 10
5 |9426 | 10
请注意,我不关心选择哪个object_key。有两个重要的要求:
- 如果有来自不同客户端的物品本中,每个客户端 件必须选择(优选同样)。
- 查询必须始终返回10行, (除少于10行外)。
建议的解决方案必须在Mysql和PostgreSQL中工作,并且从表中插入和选择它不会太昂贵。
我已经想加入像sort_idx一列并插入每个客户的实际行数每排的,所以我能做到这一点:
--------------------------------------
client_id |object_key |prio| sort_idx
--------------------------------------
1 |4711 | 10 | 1
1 |2831 | 10 | 2
1 |1912 | 10 | 3
1 |1913 | 10 | 4
1 |1914 | 10 | 5
1 |1915 | 10 | 6
1 |1922 | 10 | 7
1 |1933 | 10 | 8
1 |1944 | 10 | 9
1 |1955 | 10 | 10
1 |1966 | 10 | 11
2 |7861 | 10 | 1
2 |1234 | 10 | 2
3 |5463 | 10 | 1
3 |5464 | 10 | 2
4 |7341 | 10 | 1
4 |7342 | 10 | 2
5 |9425 | 10 | 1
5 |9426 | 10 | 2
5 |9427 | 10 | 3
select * from tbl_queue order by prio, sort_index asc limit 10;
--------------------------------------
client_id |object_key |prio| sort_idx
--------------------------------------
1 |4711 | 10 | 1
2 |7861 | 10 | 1
3 |5463 | 10 | 1
4 |7341 | 10 | 1
5 |9425 | 10 | 1
1 |2831 | 10 | 2
2 |1234 | 10 | 2
3 |5464 | 10 | 2
4 |7342 | 10 | 2
5 |9426 | 10 | 2
不过,我不是对于有效地计算每个插入的排序索引过于自信。可能会出现20.000行同时插入(或快速插入)的情况。
我不是在寻找引入一些变量或函数的解决方案,我也不想引入数据库触发器,只是普通的sql。
编辑13.09.2017 17:13:如果在spring的JdbcTemplate的上下文中使用用户定义的变量是可能的,那么我想这是一个可接受的解决方案。
不过我喜欢让事情尽可能的简单数据库层(即不使用特定数据库/独家命令)
编辑2017年9月26日11:18 所以我测试过建议的解决方案针对具有大约40,000条记录的现实生活数据集,并且我不得不发现它表现不佳。事实上,大约一分钟左右之后,我就取消了查询执行。
此查询的解释给出了下面的输出:
explain select c1.client_id,
c1.object_key,
c1.prio,
count(*)-1 as sort_idx
from clients as c1
left join clients as c2
on c1.client_id = c2.client_id
and c1.object_key >= c2.object_key
and c1.prio >= c2.prio
group by c1.client_id,
c1.object_key,
c1.prio
order by
c1.prio,
sort_idx
limit 10;
Limit (cost=512.53..512.56 rows=10 width=12)
-> Sort (cost=512.53..513.03 rows=200 width=12)
Sort Key: c1.prio, ((count(*) - 1))
-> HashAggregate (cost=505.71..508.21 rows=200 width=12)
Group Key: c1.client_id, c1.object_key, c1.prio
-> Nested Loop Left Join (cost=0.15..484.80 rows=2091 width=12)
-> Seq Scan on clients c1 (cost=0.00..29.40 rows=1940 width=12)
-> Index Only Scan using clients_idx on clients c2 (cost=0.15..0.22 rows=1 width=12)
Index Cond: ((client_id = c1.client_id) AND (object_key <= c1.object_key) AND (prio <= c1.prio))
我不是解释说明计划的专家,但只要成本数字是高还是我看到的嵌套循环连接我感觉到危险。
与密集排名函数给出的语句运行速度快很多,不幸的是我需要支持mysql和postgres。
*我不寻找解决方案引入一些变量*为什么不呢? – Strawberry
请原谅我可能是过分限制。我们使用java和org.springframework.jdbc.core.jdbcTemplate来读写我们的数据库。我不熟悉,如果使用弹簧JdbcTemplate可以使用用户定义的变量。如果是这样,我想应该没有理由不使用它们。编辑:我添加了java和jdbctemplate作为关键字 – SebastianRiemer
据推测,java只关心它收到的结果,而不是MySQL用来构造结果的步骤?如果是这样,变量对我来说似乎是个好主意。 – Strawberry