标签: postgresql

Postgres – 如何更改 postgres 索引的 WHERE 子句

我需要在一个包含大约 6 亿行的现有表上插入一个新的两字段索引。该表包含大约一年内积累的数据,每天大约添加 200 万行新行。

\n\n

我知道一次性向一个非常大的表添加新索引需要很长时间,因此为了节省时间,我首先使用以下命令仅对最后几天的数据建立索引\xe2\x80\xa6

\n\n
CREATE INDEX  idx_001\nON message (deviceNumber, messageTime)\nWHERE messageTime >='07-May-2018 00:00:00' ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

一天索引大约需要 3 小时,即大约 40 分钟。

\n\n

理想情况下,我\xe2\x80\x99d 喜欢对整个表建立索引,但如果一天的数据需要 40 分钟,一次性完成将需要一周以上的时间。

\n\n

我想我可以创建很多小索引,每个索引用于几天的数据,也许像这样\xe2\x80\xa6

\n\n
CREATE INDEX  idx_002\nON message (deviceNumber, messageTime)\nWHERE messageTime <'07-May-2018 00:00:00' AND messageTime >='01-May-2018 00:00:00'  ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

但我\xe2\x80\x99d 更喜欢坚持使用一个索引。有没有办法改变现有索引的 where 子句来增加覆盖天数?或者我必须创建很多小索引吗?

\n

postgresql performance index

3
推荐指数
1
解决办法
1093
查看次数

当前的search_path可以在查询中使用吗?

我想做这样的事情:

SELECT *
FROM information_schema.tables
WHERE table_schema IN (search_path)
Run Code Online (Sandbox Code Playgroud)

我在文档中找不到任何内容。是否可以?如何?

postgresql postgresql-9.6

3
推荐指数
1
解决办法
2091
查看次数

检查 Postgres 中 JSONB 字段的数组内的对象中是否存在属性

这是我的表数据:

对应的sqlfiddle - http://sqlfiddle.com/#!17/e3f09

create table jsonData (
    id serial primary key,
    data jsonb
);

insert into jsonData (data) values (

$${
  "b": 2,
  "c": [
    {
      "d": {
        "e": true
      }
    },
    {
      "d": {
        "e": true
      }
    },
    {
      "d": {
        "e": true,
        "f": "I'm here"
      }
    }
  ]
}
$$::jsonb),
(
$${
  "a": 1,
  "c": [
    {
      "d": {
        "e": true
      }
    },
    {
      "d": {
        "e": true
      }
    },
    {
      "d": {
        "e": true
      }
    } …
Run Code Online (Sandbox Code Playgroud)

postgresql

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

Postgres - 如果正则表达式匹配失败则返回默认值

我想尝试正则表达式匹配,null如果失败则返回。

以下查询尝试查找字符串中的第一个数字。结果会忽略带有 text 的条目'blah'。我更希望它返回一个null值。

这个问题可能与正则表达式无关,更多地与集合代数有关。我的预感是,有一种优雅的方法可以做到这一点,而不需要left join任何东西,尽管谷歌搜索被证明是徒劳的。

with test_data as (
  select 'abc 123' as txt
  union
  select 'abc 456' as txt
  union
  select 'blah' as txt
)

select
  txt,
  (regexp_matches(txt, '\d+'))[1] as first_num
from
  test_data
Run Code Online (Sandbox Code Playgroud)

postgresql pattern-matching functions set-returning-functions regex

3
推荐指数
1
解决办法
7561
查看次数

为什么并行 pg_restore 命令可能需要更长的时间才能完成其非并行等效命令?

我使用 pg_restore 从目录备份恢复 50 GB 数据库,使用以下命令,该命令使用了 4 个作业:

pg_restore -d analytics -U postgres  -j 4 -v "D:\Program Files\PostgreSQL\10\backups\Analytics_08_2018__7_53_21.36.compressed"
Run Code Online (Sandbox Code Playgroud)

我从命令行运行了这个。恢复时间比非并行恢复长约 2 小时。它似乎在恢复作业结束时继续创建索引

pg_restore: launching item 2817 INDEX nidx_bigrams_inc_hits
pg_restore: creating INDEX "public.nidx_bigrams_inc_hits"
pg_restore: finished item 2965 TABLE DATA trigrams
pg_restore: launching item 2822 INDEX nidx_trigrams_inc_hits
pg_restore: creating INDEX "public.nidx_trigrams_inc_hits"
pg_restore: finished item 2823 INDEX nidx_unigrams_inc_hits
pg_restore: finished item 2822 INDEX nidx_trigrams_inc_hits
pg_restore: finished item 2817 INDEX nidx_bigrams_inc_hits
pg_restore: finished main parallel loop
Run Code Online (Sandbox Code Playgroud)

每个 pg_restore“创建索引”作业在 pg_stat_activity 中的状态均为“空闲”。另一个 pg_restore 作业在提交时“空闲”。

我希望并行恢复能够比默认恢复快得多,而且它似乎一直在这样做,直到大约 …

postgresql parallelism pg-restore postgresql-10

3
推荐指数
1
解决办法
7862
查看次数

显示一个字段中具有非唯一值的行

我熟悉如何聚合行,如这个答案所示:

我还熟悉如何使用 HAVING 子句过滤聚合结果。

我似乎无法理解(因此它会粘住)是如何根据值或比较其他行来过滤行,而不聚合它们。

我知道答案涉及一些有关窗口函数或窗口子句的内容,事实上我以前已经成功完成过。但我似乎并没有记住它是如何运作的;我觉得我错过了一些基本的东西。

举个例子,信息如下:

 fruit_name | some_field 
------------+------------
 apple      |       3.25
 apple      |        6.8
 apple      |        0.7
 orange     |        2.6
 banana     |        3.5
 banana     |       2.49
 cherry     |          1
 grapefruit |        2.6
 grapefruit |        2.7
Run Code Online (Sandbox Code Playgroud)

我想要获取行数(按水果名称)大于 1 的所有行,因此它应该如下所示:

 fruit_name | some_field 
------------+------------
 apple      |       3.25
 apple      |        6.8
 apple      |        0.7
 banana     |        3.5
 banana     |       2.49
 grapefruit |        2.6
 grapefruit |        2.7
Run Code Online (Sandbox Code Playgroud)

执行此操作的正确惯用方法是什么?

(如果可能的话,我想要一个 SQL 标准答案,如果有一种更简单的 Postgres 特定方法来做到这一点,我也想知道。)

postgresql select window-functions

3
推荐指数
1
解决办法
1855
查看次数

实时性远大于“EXPLAIN ANALYZE”的执行时间(索引扫描)

我想根据 ID 获取最多 100 行。id 是表的主键。

我编写的查询如下所示:

select * from table where id = any ($1);
Run Code Online (Sandbox Code Playgroud)

其中$1被插值为 ids 数组。

使用时EXPLAIN ANALYZE我得到以下计划(解释链接):

                                                                QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.43..44.98 rows=17 width=553) (actual time=100.048..834.209 rows=17 loops=1)
   ->  Index Scan using instagram_id_index_1000 on profiles_1000  (cost=0.43..44.98 rows=17 width=553) (actual time=100.046..834.163 rows=17 loops=1)
         Index Cond: (id = ANY ('{34491540,28977916,33241270,33609141,31043380,29364420,30247037,33311491,36267571,32886281,32366574,32569254,33038689,31089076,29416100,30455309,31570597}'::integer[]))
 Planning time: 424.512 ms
 Execution time: 834.280 ms
(5 rows)
Run Code Online (Sandbox Code Playgroud)

当我实际执行它时(使用\timing),我得到的结果在 2-5 秒范围内!我真的无法接受如此糟糕的表现。EXPLAIN ANALYZE首先提供的执行时间就已经很长了。

一些上下文:
1)数据库是本地的,所以没有网络延迟
2)我查询的表是物化视图
3)我也尝试了 …

postgresql performance query-performance

3
推荐指数
1
解决办法
7578
查看次数

如何选择多个值到数组中并循环?(postgres 9.3)

为了便于论证,我有一个简单的表格。我有一个选择 ids 并循环它们的函数,称为loop_test. 我可以选择一个 id 数组并循环它们,从而导致我在事务中进行更改。

CREATE OR REPLACE FUNCTION loop_test() RETURNS void AS $$
DECLARE
        _ids_array INTEGER[];
        _id INTEGER;
BEGIN
        SELECT ARRAY(SELECT id FROM loop_test) INTO _ids_array; 
        FOREACH _id IN ARRAY _ids_array
        LOOP
                UPDATE loop_test SET looped = TRUE WHERE id = _id;
        END LOOP;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

桌子:

db=# \d loop_test;
      Table "public.loop_test"
    Column     |  Type   | Modifiers 
---------------+---------+-----------
 id            | integer | 
 other_id      | integer | 
 id_copy       | integer | 
 other_id_copy | integer | …
Run Code Online (Sandbox Code Playgroud)

postgresql aggregate array

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

将字符串模式与任何数组元素匹配

我正在尝试将字符串模式与数组中的任何字符串进行匹配:

SELECT 'abc' LIKE ANY('{"abc","def"}') -- TRUE

-- BUT

SELECT 'ab%' LIKE ANY('{"abc","def"}') -- FALSE, I expect TRUE
Run Code Online (Sandbox Code Playgroud)

第二个查询有什么问题?

postgresql

3
推荐指数
1
解决办法
3897
查看次数

Postgres 中的插入和只读表

我想创建一个“不可变”的Postgres数据库,用户只能insert/ select(写入/读取)数据,但不能update/ delete(更改/删除)。

我知道有FOR UPDATE锁,但不知道如何使用它。

假设我有下表,如何使其不可变(或者,如果我理解正确,如何FOR UPDATE永久使用锁)?

CREATE TABLE account(
 user_id serial PRIMARY KEY,
 username VARCHAR (50) UNIQUE NOT NULL,
 password VARCHAR (50) NOT NULL,
 email VARCHAR (355) UNIQUE NOT NULL,
 created_on TIMESTAMP NOT NULL,
 last_login TIMESTAMP
);
Run Code Online (Sandbox Code Playgroud)

postgresql permissions read-only-database

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