如何改进此查询以将下面显示的查询速度从30+ 秒提高到毫秒?我正在使用PostgreSQL: v 9.6.6。
我有一个时间序列表buildings.hispoint,用于存储表中数据点的历史数据buildings.point。
我需要Max(value) - Min(value) as aggregation_value为大量数据点汇总不同时间范围(例如,年初至今)的数据。
事实证明,这非常缓慢,需要改进。
buildings.hispoint (20,210,129行)CREATE TABLE buildings.hispoint (
id int,
value float,
datetime timestamp,
point_id …
CONSTRAINT foo FOREIGN KEY (point_id)
REFERENCES buildings.point (point_id),
…
);
Run Code Online (Sandbox Code Playgroud)
SELECT COUNT(datetime) AS id,
MAX(value) - MIN(value) AS aggregation_value
FROM buildings_hispoint
WHERE point_id = 44
AND buildings_hispoint.datetime BETWEEN '2018-01-01 00:00:00' AND '2018-05-02 09:18:14';
Run Code Online (Sandbox Code Playgroud)
Aggregate (cost=160967.11..160967.12 rows=1 width=16) (actual time=21713.720..21713.720 rows=1 …Run Code Online (Sandbox Code Playgroud) postgresql performance aggregate postgresql-9.6 time-series-database query-performance
我绝不是数据库专家,所以我可能会问一些愚蠢的问题。
所以我正在使用 PostgreSQL,我想对一个表进行插入,保留 ID(ID 自动递增)并将一个元组插入另一个表(元组中有该 ID)。
显然我想让事情保持原子性。
询问:
WITH inserted AS (
INSERT INTO
"public"."user" (email, first_name, last_name, username)
VALUES
(?, ?, ?, ?)
RETURNING id
)
INSERT INTO
"public"."security" (user_id, security)
VALUES((
SELECT id FROM inserted
), ?);
Run Code Online (Sandbox Code Playgroud)
问题是,这甚至可以工作吗?如果第二次插入失败会发生什么?第一个会坚持下去吗?
显而易见的答案是,我可能会将其放入事务并提交/回滚,但这是否足够?
我想看看是什么应用程序是原因,但即使我更改为用户 postgres 并运行 psql,它仍然会抛出错误
该关系是在 Postgres 9.6 中使用以下命令创建的:
CREATE TABLE import_event (
import_event_id BIGINT NOT NULL,
filename VARCHAR (200) CONSTRAINT NN_import_event__filename NOT NULL
);
ALTER TABLE ONLY import_event ADD CONSTRAINT PK_import_cak_key PRIMARY KEY (import_event_id);
Run Code Online (Sandbox Code Playgroud)
请注意,not null 约束已命名。
然后执行了下面的命令
insert into import_event (import_event_id) values (1);
Run Code Online (Sandbox Code Playgroud)
当然,约束违反错误被提出。消息内容如下
ERROR: null value in column "filename" violates not-null constraint
DETAIL: Failing row contains (1, null).**strong text**
Run Code Online (Sandbox Code Playgroud)
问题是该消息中缺少非空约束的名称。但是,正确的错误消息:
ERROR: new row for relation "import_event" violates check constraint "nn_import_event__filename"
Run Code Online (Sandbox Code Playgroud)
当非空约束声明如下时产生
ALTER TABLE ONLY import_event ADD CONSTRAINT NN_import_event__filename CHECK(filename IS NOT NULL); …Run Code Online (Sandbox Code Playgroud) 除了写作风格之外,还有什么优势吗?
CREATE TABLE foo (
a int PRIMARY KEY,
b int
);
Run Code Online (Sandbox Code Playgroud)
进而,
CREATE TABLE bar (
a int REFERENCES foo,
c int
);
Run Code Online (Sandbox Code Playgroud)
超过,
BEGIN;
CREATE TABLE bar (
a int,
c int
);
ALTER TABLE bar
ADD FOREIGN KEY (a)
REFERENCES foo;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
我正在尝试构建一个 DDL 生成器,所以我想知道是否需要支付对列的约束(我之前生成它们的地方),或者将它们全部移到表之外?我知道这些结果产生了相同的表格,我只是想知道引擎盖下是否有任何优势——更少的沃尔玛?等等?
有这样的问题 - 超过 2000 万行的表。
当我使用默认值添加新列时 - postgresql 锁定表超过 40 分钟,因此我的应用程序此时停止工作。
所以代替
ALTER TABLE "test" ADD COLUMN "field" boolean DEFAULT True NOT NULL;
Run Code Online (Sandbox Code Playgroud)
我愿意
ALTER TABLE "test" ADD COLUMN "field" boolean NULL;
ALTER TABLE "test" ALTER COLUMN "field" SET DEFAULT true;
Run Code Online (Sandbox Code Playgroud)
之后每个新行默认为 true,所以现在我需要更新 2000 万个当前行。我分批更新它们:
WITH cte AS (
SELECT id as pk
FROM "test"
WHERE "field" is null
LIMIT 10000
)
UPDATE "test" table_
SET "field" = true
FROM cte
WHERE table_.id = cte.pk
Run Code Online (Sandbox Code Playgroud)
之后我做
ALTER TABLE "test" ALTER …Run Code Online (Sandbox Code Playgroud) 我想转储一个表的全部内容,按主键排序。直觉上,我想做一个
SELECT * FROM %table_name% ORDER BY %primary_key_of(table_name)%;
Run Code Online (Sandbox Code Playgroud)
这将由外部工具运行,知道表的列表,但不知道它们的主键。
如果没有更好的选择,我们可以假设所有的主键都是单列的。
我使用的是 PostgreSQL-9.5,但可以升级。
我最近在 Postgres 中遇到了这种奇怪的行为。我有一张像下面这样的表:
sasdb=# \d emp_manager_rel
表“db3004db.emp_manager_rel”
专栏 | 类型 | 整理 | 可空 | 默认
------------+--------+-----------+------------+----- ----
emp_id | bigint | | |
manager_id | bigint | | |
select * from emp_manager_rel ;
emp_id | manager_id
--------+------------
1 | 123
我执行了以下更新语句:
更新1:
更新 emp_manager_rel 设置 manager_id = manager_id+emp_id , emp_id=emp_id*4;
更新表格如下:
emp_id | manager_id
--------+------------
4 | 124
更新 2:我执行了以下查询(在原始表上,而不是在更新表上)
更新 emp_manager_rel 设置 emp_id=emp_id*4 , manager_id = manager_id+emp_id ;
它更新表格如下:
emp_id | manager_id
--------+------------
4 | 124
我期望 …
我有一个date具有以下值格式的类型列:(YYYY-MM-DD例如。2018-08-03)。我想获得与日期等效的 unix 时间戳,但没有时区。
Fe 日期2018-08-03应该相等1533254400(从这里计算)。
我试过了,to_timestamp(my_date_column, 'YYYY-MM-DD')但它返回 error function to_timestamp(date, unknown) does not exist。我尝试::timestamp...在函数调用结束时添加不同的变体,但无济于事。
目前我在应用程序层进行时间戳转换,但我想将该工作专用于数据库。
我有一个重新创建我的单元测试数据库的 sql 脚本。目前它与\i <path_to_my_script>. 它就像
// create user, give him some priveleges
CREATE DATABASE my_database;
CREATE TABLE my_table (
id UUID primary key,
data json
);
Run Code Online (Sandbox Code Playgroud)
但是my_table是在postgres数据库中创建的,而不是在my_database.
如何指定my_table应该在 中创建my_database?
我使用 postgresql 10.5。
postgresql ×10
constraint ×2
performance ×2
aggregate ×1
alter-table ×1
cte ×1
date ×1
ddl ×1
foreign-key ×1
primary-key ×1
sql-standard ×1
timestamp ×1
transaction ×1
update ×1