TLDR:我可以创建一个由以下WHERE子句使用的索引吗:
WHERE foo_date <@ tsrange('2018-01-01', '2018-02-01')
Run Code Online (Sandbox Code Playgroud)
创建表 foo
(
foo_id INTEGER 由默认身份生成,
不带时区的 foo_date 时间戳 NOT NULL,
约束 foo_pkey 主键 (foo_id)
);
此表包含 100,000 条记录,日期从2009-01-01到2018-12-29。我希望能够查询给定日期范围内的行(例如 2018 年 1 月的行)。
一种方法是使用BETWEEN运算符:
SELECT * FROM foo WHERE foo_date BETWEEN '2018-01-01' AND '2018-01-31';
这种方法的问题是,如果foo_date发生在2018-01-31午夜之后,它们将不会包含在此查询中。所以我可以将查询更改为BETWEEN '2018-01-01' AND '2018-02-01'. 那么问题来了,然而,上发生的记录2018-02-01 00:00:00。这些将被包括在内,这是我不想要的。
Aaron Bertrand提出的另一种选择是使用这个结构:
foo_date >= '2018-01-01' AND foo_date < '2018-02-01'
Run Code Online (Sandbox Code Playgroud)
(是的,此博客适用于 …
我刚刚将我的 AWS RDS 数据库实例从 Postgresql 升级v9.6到v10.6-R1. 我使用仪表板下数据库部分中的“修改”选项卡手动执行此操作。紧接着,作为主用户,我失去了在public架构中执行任何操作的能力。
我可以毫无问题地连接到数据库,但是当我尝试在公共模式中的表上运行 select 语句时看到此错误: ERROR: permission denied for schema public
看来我的rds_superuser用户无法再登录(freetiersuperuser是我的主用户的名称,尽管它的名称具有误导性):
master_prod=> \du+
List of roles
Role name | Attributes | Member of | Description
-------------------+------------------------------------------------------------+-------------------------------------------------------------+-------------
freetiersuperuser | Create role, Create DB +| {rds_superuser} |
| Password valid until infinity | |
rds_iam | Cannot login | {} |
rds_password | Cannot login | {} |
rds_replication | Cannot login | {} |
rds_superuser …Run Code Online (Sandbox Code Playgroud) 我有一张桌子“会话”
CONSTRAINT u_session UNIQUE (where, who, when)
Run Code Online (Sandbox Code Playgroud)
我需要使用 (where, who, when) 的组合作为表“结果”中的外键。我该怎么做?
在我的交易中,我正在创建一个临时表:
create temporary table x on commit drop as
select ...
Run Code Online (Sandbox Code Playgroud)
我还在该表上添加了一个索引:
create index on x(some_column);
Run Code Online (Sandbox Code Playgroud)
现在有必要analyze在那个桌子上跑吗?或者我是否只需要在索引创建后分析表的更新/删除?
换句话说,我的问题是:索引的创建是否已经意味着analyze执行?
想象一下关于猫主人的下表。
drop table if exists owners cascade;
create table owners(
id bigint primary key generated always as identity ,
name text not null
)
;
insert into owners(name)
select random()::text from generate_series(1,20000);
--insert 200,000 owners records
Run Code Online (Sandbox Code Playgroud)
当我删除一些所有者记录时,速度非常快:
delete from owners
where id %10 = 0;
Run Code Online (Sandbox Code Playgroud)
85 毫秒内影响了 20000 行
现在我添加一个名为“cats”的表,它指的是所有者:
drop table if exists cats;
create table cats(
id serial primary key ,
name varchar(20000) not null,
owner_id int not null references owners(id)
);
--insert 1bn cats records
insert into …Run Code Online (Sandbox Code Playgroud) CREATE TABLE IF NOT EXISTS ttable (
tcol decimal(9,7)
);
Run Code Online (Sandbox Code Playgroud)
insert into ttable(tcol) values(17.4604786);
Run Code Online (Sandbox Code Playgroud)
该值被存储为 17.46
如果我使用十进制/数字类型,也会发生同样的情况
我
在 x86_64-apple-darwin16.7.0 上
使用
PostgreSQL 11.2,由 Apple LLVM 版本 8.1.0 (clang-802.0.42) 编译,64 位。
工具
SQL Workbench/J Build 124 (2018-08-20 22:43)
Java 版本:1.8.0_211(64 位)。
连接信息:
产品名称:PostgreSQL
产品版本:11.2
产品信息:11.2
驱动程序名称:PostgreSQL JDBC 驱动
程序驱动程序类:org.postgresql.Driver
驱动程序版本:42.2.6
隔离级别:READ COMMITTED
Workbench DBID:postgresql
我有一张超过 5000 万条记录的表。其中一个字段是COLOR_CODE。我在列上设置了一个索引,COLOR_CODE如下所示:
"mytable_colorcode_idx" btree (color_code)
Run Code Online (Sandbox Code Playgroud)
我注意到当我运行下面的查询时,执行时间更长
SELECT count(total_amount) FROM mytable
WHERE color_code in ('red','green') and sale_date = '1970'
Run Code Online (Sandbox Code Playgroud)
但是,使用OR子句执行时间更快:
SELECT count(total_amount) FROM mytable
WHERE color_code = 'red' or color_code = 'green' and sale_date = '1970'
Run Code Online (Sandbox Code Playgroud)
查询计划 IN
explain analyze SELECT count(total_amount) FROM mytable
WHERE color_code in ('red','green') and sale_date = '1970'
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=2074238.07..2074238.08 rows=1 width=8) (actual time=63520.150..63520.150 rows=1 loops=1)
-> Bitmap Heap Scan on mytable (cost=53504.73..2069923.27 rows=1725919 width=6) (actual time=3509.920..63080.519 …Run Code Online (Sandbox Code Playgroud) 我已经尝试对内置 upsert (INSERT ... ON CONFLICT UPDATE ...) 的性能影响进行了一段时间的研究,当进行了大量 upsert 时。规模大约是每小时 100 万条记录,分为每组大约 300 条记录。
该表相当简单,只有几个 int/bool 字段和一个日期字段。该表的总大小介于 50-6000 万条记录之间。本质上,所有行都应该在某个周期(目前大约为 2 天)内保持最新。有时很多信息会发生变化,有时很少/没有信息变化(例如 300 条记录被更新,但它们与现有记录相同)。
到目前为止,一个假设是,这个项目似乎正在遭受不断发生的大量写入的痛苦,因为即使 upsert 导致没有插入/更新,来自 upsert 的“失败”插入仍然会被写入某个地方(根据我们的知识)。因此,我们的想法是利用老式的 upsert(可写 CTE)并执行更精细的操作,以确保仅插入尚不存在的数据,并且仅更新实际更改的数据。然而,这自然会给数据库带来更多的读取负载并增加查询的复杂性。
问题是,从性能的角度来看,内置 upsert 是无用的(例如,它只适用于更小的任务),我们的假设是正确的,还是我们错了?我阅读了一些关于 HOT 更新和 autovacuum 调整的内容,但没有任何内容引用与此问题更相似的内容。
值得一提的是,这个数据库(PostgreSQL 10.9)在 Heroku 上运行,所以我们无法根据需要对其进行调整。我们计划在某个时候搬家,这取决于它最终的重要性。最后,还值得一提的是,这个DB还有一个follower(即只读副本)。
真的很感激对此有一些好的见解!先谢谢了。
我一直在尝试使用 tsvector 索引进行全文搜索,并且看到在 tsvector 类型的列中生成一个存储向量是一种常见的做法。我们使用的是 Postgres 11.4,但我已经看到这种做法用作 PG 12 生成列的示例。(比出于相同目的使用触发器更简单。)
我的问题是,有什么好处?我在文本字段的 tsvector 上尝试了表达式 GIN 索引,并在存储的 tsvector 上尝试了 GIN 索引。本地大约有 800 万行,我无法测量任何有意义的速度差异。鉴于将向量存储为列和索引需要更多空间,我很好奇是否有明显的情况证明额外成本是合理的。例如,当您有更多角色时。
注意:我们将文本存储在数据库中,因此这不是您在不将源文本吸收到数据库中的情况下索引外部页面/文档/等的设置之一。
我想向连接到 Postgresql 数据库的用户展示横幅 motd(今日消息)。类似于您使用的 cisco 路由器和交换机 cli:
banner motd "Seien Sie bitte vorsichtig....."
Run Code Online (Sandbox Code Playgroud)
然后在登录交换机/路由器时,您会看到该消息。
我想在连接到数据库时看到类似的东西。
例子:
$ psql postgres
psql (12.0)
Type "help" for help.
Seien Sie bitte vorsichtig.....
postgres=#
Run Code Online (Sandbox Code Playgroud) postgresql ×10
index ×3
performance ×2
amazon-rds ×1
datatypes ×1
foreign-key ×1
optimization ×1
permissions ×1
range-types ×1
timestamp ×1
upgrade ×1
upsert ×1
vacuum ×1