如何将值数组存储到变量中

时间:2020-11-01 20:31:39

标签: postgresql psql

我有一个执行复杂负载平衡的功能,我需要首先找出空闲服务器的列表。之后,我必须遍历该列表的一个子集,最后我必须做很多复杂的事情,所以我不想一遍又一遍地不断查询该列表。参见以下示例(请注意,这仅是PSUEDO CODE)。

CREATE OR REPLACE FUNCTION load_balance (p_company_id BIGINT, p_num_min_idle_servers BIGINT)
RETURNS VOID
AS $$
DECLARE
    v_idle_server_ids BIGINT [];
    v_num_idle_servers BIGINT;
    v_num_idle_servers_to_retire BIGINT;

BEGIN
    PERFORM * FROM server FOR UPDATE;

    SELECT
        count(server.id)
    INTO
        v_num_idle_servers
    WHERE
        server.company_id=p_company_id
    AND
        server.connection_count=0
    AND
        server.state = 'up';

    v_num_idle_servers_to_retire = v_num_idle_servers - p_num_min_idle_servers;

    SELECT
        server.id
    INTO
        v_idle_server_ids
    WHERE
        server.company_id=p_company_id
    AND
        server.connection_count=0
    AND
        server.state = 'up'
    ORDER BY
        server.id;

    FOR i in 1..v_num_idle_servers_to_retire
        UPDATE
            server
        SET
            state = 'down'
        WHERE
            server.id = v_idle_server_ids[i];

问题:我当时正在考虑获取服务器列表,并逐一遍历它们。在postgres中有可能吗?

注意:我尝试将所有内容放在一个查询中,但是由于存在多个联接和子查询,因此非常非常复杂。例如,一个系统在三个不同的服务器上运行着三个应用程序,这些应用程序知道它们的负载,但是服务器知道它们的公司隶属关系,因此我需要将系统加入到应用程序中,并将应用程序加入到服务器中

1 个答案:

答案 0 :(得分:1)

经验法则:如果您使用SQL循环,则可能是更好的方法。

您要set state = 'down'直到拥有一定数量的空闲服务器。

我们可以在一个语句中完成此操作。使用Common Table Expression查询您的空闲服务器,并将其提供给update from。如果您经常这样做,则可以将CTE转换为视图。

但是我们需要根据有多少个空闲服务器来限制拆卸的数量。我们可以做到这一点。但是update from没有限制,因此我们需要第二个CTE来限制结果。

在这里,我已经硬编码了company_id 1和p_num_min_idle_servers 2。

with idle_servers as (
  select id
  from server
  where server.company_id=1
    and connection_count=0
    and state = 'up'
),
idle_servers_to_take_down as (
  select id
  from idle_servers
  -- limit doesn't work in update from
  limit (select count(*) - 2 from idle_servers)
)
update server
set state = 'down'
from idle_servers_to_take_down
where server.id = idle_servers_to_take_down.id

这样做的好处是,只需执行一条语句即可避免争用情况,而不必锁定整个表。

Try it

相关问题