标签: postgresql

使用 SIMILAR TO 和许多前缀优化查询

我在 PostgreSQL 9.6中有一个查询需要很长时间才能运行:

SELECT DISTINCT ON (gc.number)
       gc.number, gc.code, ch.client_id, ch.client_parent_id
FROM client gc, client_hierarchy ch
WHERE gc.code = ch.client_id
AND gc.number in (SELECT NUMB FROM directory
                  WHERE ACTIVE = TRUE
                  AND NUMB SIMILAR TO '(ABTR|GREW|POEW)%');
Run Code Online (Sandbox Code Playgroud)

SIMILAR TO接收许多不同NUMB的作为参数。ABTR|GREW|POEW大约 3.500 多。

表定义:

CREATE TABLE directory (
    id BIGINT PRIMARY KEY NOT NULL,
    active BOOLEAN NOT NULL,
    numb VARCHAR(8),
    branch VARCHAR(20),
    city VARCHAR(50),
    modified_date TIMESTAMP NOT NULL,
    name VARCHAR(200)
);
CREATE INDEX dir_numb_index ON directory (numb); …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index postgresql-performance

5
推荐指数
1
解决办法
123
查看次数

PostgreSQL外表插入违反主键约束10

我有两个本地数据库,其中一个我创建了一个引用第二个数据库中的表的外部表。当我想在外部表中插入时,它会从 1 开始插入主键,尽管当我在实际表中插入时,它会从输入的最后一个值继续。有什么办法,所以如果我插入实际或外表,它会按主键的顺序排列吗?

CREATE TABLE Actual_Table (
  id   serial   PRIMARY KEY
  name varchar
);
Run Code Online (Sandbox Code Playgroud)

然后我在实际表中插入一些数据

INSERT INTO Actual_Table (name) VALUES
  ('AHMAD'),
  ('MAHMOOD');
Run Code Online (Sandbox Code Playgroud)

然后我在第二个数据库中创建以下外部表

CREATE FOREIGN TABLE Foreign_Table (
  id serial,
  name varchar
) server some_server options(schema_name 'public', table_name 'Actual_Table')
Run Code Online (Sandbox Code Playgroud)

然后当我使用以下插入语句用户插入外表时,我收到一个违反主键约束的错误

INSERT INTO Foreign_Table (name) VALUES ('John');
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误

ERROR:  duplicate key value violates unique constraint "to_copy_pkey"
DETAIL:  Key (id)=(2) already exists.
CONTEXT:  Remote SQL command: INSERT INTO public.to_copy(id, name) VALUES ($1, $2)
Run Code Online (Sandbox Code Playgroud)

postgresql primary-key postgresql-9.5

5
推荐指数
1
解决办法
1968
查看次数

PostgreSQL 9.4 深度合并 jsonb 值

要求和情况

我们目前正在使用 JSONB 列来加速我们数据库中的任意搜索,并且到目前为止工作正常。更新数据时,要求如下:

  • 任何新值都将覆盖任何现有值。这包括空值和数组。
  • 任何(嵌套)对象都将被合并。
  • 空值以及空数组和对象将被删除(如果它们存在的话)。

为了说明这一点,请考虑以下示例:

现有(为了说明目的包含空值):

{
  "a":null, 
  "b":1, 
  "c":1,
  "f":1, 
  "g": { 
     "nested": 1 
  }
}
Run Code Online (Sandbox Code Playgroud)

这应该合并到现有对象中:

{
  "b":2, 
  "d":null, 
  "e":2, 
  "f":null, 
  "g":{
    "nested": 2
  }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我们覆盖了一些字段并删除了f. 所以预期的输出是:

{
  "b": 2, //overridden
  "c": 1, //kept
  "e": 2, //added
  "g": {
    "nested": 2 //overridden
  }
}
Run Code Online (Sandbox Code Playgroud)

为了实现这一点,我们使用以下函数:

CREATE OR REPLACE FUNCTION jsonb_merge(jsonb1 JSONB, jsonb2 JSONB) 
RETURNS JSONB LANGUAGE sql IMMUTABLE
AS $$
  SELECT  
    CASE    
      WHEN jsonb_typeof($1) = 'object' AND jsonb_typeof($2) = 'object' THEN
        ( …
Run Code Online (Sandbox Code Playgroud)

postgresql json postgresql-9.4

5
推荐指数
1
解决办法
5929
查看次数

在每个租户模式的模式中更改 postgres 中的搜索路径的成本是多少

我正在研究多租户存储网关。

每个租户都有自己的架构——每个租户的架构是一个元架构,因此每个租户架构都是相同的。数据库交互仅通过存储过程 API 发生。存储过程层位于公共架构上。存储过程依赖于设置为 的 search_path <TENANT_SCHEMA>;public

应用层根据公共模式中的存储过程准备语句。

我有一个用于切换租户的存储过程,如下所示:

CREATE OR REPLACE FUNCTION domains_switch(domain DOMAIN_NAME) RETURNS VOID AS $$ BEGIN
  IF EXISTS (SELECT NULL FROM public.domains WHERE domain_name = domain) THEN
    EXECUTE format('set search_path=%s,public;', domain);
  ELSE
    RAISE 'domain "%" does not exist',domain USING ERRCODE = 'AX001';
  END IF;
  RETURN; END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

plpgsql存储过程自己管理计划,这意味着我只需要在网关中为每个后端准备一次 api 语句。我怀疑当我切换模式时存储过程的内部缓存计划无效。

我计划在网关的连接池管理中添加一个层,以最小化 search_path 开关。我的直觉正确吗?这是正确的做法吗?

postgresql performance postgresql-performance

5
推荐指数
1
解决办法
828
查看次数

SQL 注释随着 psql 和 `\e` 消失

无论如何,有没有改变psql. 以下面的查询为例。执行它。

CREATE TABLE foo
AS
  SELECT x AS id,
    -- x AS id2,
    x AS id3
  FROM generate_series(1,50) AS x;
Run Code Online (Sandbox Code Playgroud)

在 psql 中运行它。然后运行\e。至少现在,对我来说,我在编辑器中看到的是没有一行。这真让我抓狂。有没有办法解决这个问题。 传递给编辑器的缓冲区中没有注释。通常,它被评论而不是被删除,因为我想在以后取消评论它。

评论不见了

postgresql psql comments

5
推荐指数
1
解决办法
247
查看次数

PostgreSQL DELETE 查询挂起(EXPLAIN ANALYZE 也是如此!)

我正在尝试从匹配查询的表中删除一堆行。我的查询的一般形式是:

DELETE FROM mytable WHERE _id IN (SELECT _id FROM mytable WHERE ...);

_id列是一个SERIAL PRIMARY KEY.

如果我自己运行内部SELECT查询,它会在大约 1 秒内运行并返回大约 100,000 行。但是,当我将DELETE调用添加到它时,它似乎只是坐下来大口大口地走开。大口大口地走开。我让它运行了大约一分钟左右,然后假设没有取得任何进展就取消了它。

我添加EXPLAIN ANALYZE到它的前面,看看我是否可以检查什么花了这么长时间,但那个电话也挂了很长时间。

任何人都可以告诉我可能会发生什么,以便可以非常快速地识别我想要删除的行,但需要不确定的时间来删除它们?

更新:完整查询如下。

DELETE FROM cards 
WHERE _id IN (
    SELECT _id
    FROM cards
    LEFT JOIN game_results ON game_results.card_id = cards._id 
    WHERE NOT available
    AND game_id IS NULL
)
Run Code Online (Sandbox Code Playgroud)

表格的简化版本是:

CREATE TABLE cards (_id INTEGER PRIMARY KEY, available BOOLEAN);
CREATE TABLE games (_id INTEGER PRIMARY KEY);
CREATE …
Run Code Online (Sandbox Code Playgroud)

postgresql

5
推荐指数
2
解决办法
1万
查看次数

如何以原子方式替换表数据的子集

在 PostgreSQL 9.6 我有一个T这样的表

category | id | data
---------+----+------
A        | 1  | foo
A        | 2  | bar
A        | 3  | baz
B        | 4  | eh
B        | 5  | whatcomesafterfoobarbaz
Run Code Online (Sandbox Code Playgroud)

有一个视图V为我提供了数据T,所以它有列category, id, dataT本质上是 的物化视图V,除了我需要以比“刷新所有内容”更多的粒度来刷新它。

所以我会选择V例如

SELECT * FROM V WHERE category = 'A';
Run Code Online (Sandbox Code Playgroud)

或者

SELECT * FROM V WHERE category = 'A' AND id = 2;
Run Code Online (Sandbox Code Playgroud)

T用任何data V …

postgresql concurrency locking update postgresql-9.6

5
推荐指数
1
解决办法
1136
查看次数

为什么这种隐式连接的规划方式与显式连接不同?

在这个答案中,我解释了 SQL-89 的隐式语法。
但是我在玩的时候注意到不同的查询计划:

EXPLAIN ANALYZE
  SELECT *
  FROM (values(1)) AS t(x), (values(2)) AS g(y);

                                     QUERY PLAN                                     
------------------------------------------------------------------------------------
 Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)
 Planning time: 0.052 ms
 Execution time: 0.020 ms
(3 rows)
Run Code Online (Sandbox Code Playgroud)

与此相反:

EXPLAIN ANALYZE
  SELECT *
  FROM (values(1)) AS t(x)                      
  CROSS JOIN (values(2)) AS g(y);
                                           QUERY PLAN                                           
------------------------------------------------------------------------------------------------
 Subquery Scan on g  (cost=0.00..0.02 rows=1 width=4) (actual time=0.004..0.005 rows=1 loops=1)
   ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)
 Planning time: 0.075 ms
 Execution time: 0.027 …
Run Code Online (Sandbox Code Playgroud)

postgresql performance join execution-plan postgresql-9.5 postgresql-performance

5
推荐指数
1
解决办法
1270
查看次数

是否可以使用 plpgsql 或 SQL 创建用户定义的类型?

不同于DOMAIN我想知道是否可以在没有 C 的情况下创建用户定义的类型。

具体来说,我想创建一个这样的类型

CREATE TYPE name (
    INPUT = input_function,
    OUTPUT = output_function
    [ , RECEIVE = receive_function ]
    [ , SEND = send_function ]
    [ , TYPMOD_IN = type_modifier_input_function ]
    [ , TYPMOD_OUT = type_modifier_output_function ]
    [ , ANALYZE = analyze_function ]
    [ , INTERNALLENGTH = { internallength | VARIABLE } ]
    [ , PASSEDBYVALUE ]
    [ , ALIGNMENT = alignment ]
    [ , STORAGE = storage ]
    [ , LIKE = like_type …
Run Code Online (Sandbox Code Playgroud)

postgresql datatypes plpgsql

5
推荐指数
1
解决办法
386
查看次数

在查询 postgres 数据库的过程中磁盘空间不足

数据库上的 SELECT 查询(带有表 JOIN)在运行时会影响磁盘空间吗?

背景:我有一个带有 Postgresql 后端的 Django 应用程序 (9.3.10)。我的数据库驻留在磁盘空间严重不足的虚拟机中(大约还剩 400MB)。

我查询了几个表以评估要弃用哪些数据以释放磁盘空间(这些包括跨表连接)。这些分析类型的查询被捆绑在一个单一的 url 后面,并统一运行。当我点击 url 时,包含我的数据库的虚拟机在大约半分钟后空间不足。

我是一个偶然的 DBA,仍在学习绳索。谁能解释为什么我在这种情况下空间不足?在此类操作中是否创建了某种临时文件?如果需要,我将分享我的配置详细信息。

postgresql postgresql-9.3

5
推荐指数
1
解决办法
4587
查看次数