我刚刚在具有 32GB RAM 和 320GB 固态磁盘的服务器上安装了 Postgres 9.1。
我将使用这台服务器来为我的站点和我的数据库提供服务(即它不仅仅是一个数据库服务器)。数据库是 500m 行,大约 120GB 的数据。
加载数据后,需要针对 SELECT 查询优化数据库 - 数据本质上是相当静态的,并且每三个月仅更改一次。对数据库进行的 99% 的查询都是读取。
我想知道什么是好的 Postgres 设置开始。我已经设置:
effective_cache_size 8GB
shared_buffers 4GB
Run Code Online (Sandbox Code Playgroud)
在 Postgres 配置文件中,但我没有触及任何其他默认值。
使用上面的设置,我发现在我的表中的一个字段上创建索引非常慢(一个多小时并且仍在运行),我想创建其中的许多。
是否还有其他设置可以让我更快地创建索引?或者我可以安全地增加这些设置吗?
基本上,我有一个数据集,它是附加到 ID 的内部位置标识符列表(因此每个“一组”地理点都有自己的 ID)。因此,表中存在“id”列和“location”列。
我需要一种方法来查找包含两个不同位置的 ID,即:
身份证 | 地点 -------------- 1 | 一种 1 | 乙 1 | C 2 | 一种 2 | C 2 | d
如果我寻找 'a' 和 'd',我会得到 2。
如果我寻找 'a' 和 'b',我会得到 1。
如果我寻找 'a' 和 'c',我会得到1或2。
我正在使用 PostgreSQL 9.4。
WITH upsert AS (UPDATE tbl SET a = 2 WHERE a = 1 RETURNING tbl.*)
INSERT INTO tbl (a)
SELECT 1 WHERE NOT EXISTS( SELECT * FROM upsert )
RETURNING *
Run Code Online (Sandbox Code Playgroud)
这个“upsert”语句有效,但是我想检索 UPDATE 或 INSERTED 值。当 upsert 执行INSERT(行尚未在 db 中)时,插入的值将从查询中正确返回。
但是,当UPDATE执行时,不会返回任何值(但行是更新的)。我试过添加,RETURNING upsert.*但它产生错误missing FROM-clause entry for table \"upsert\"。
我正在尝试设置备用服务器并不断收到此错误。我的主服务器有足够多的连接来处理负载:
listen_addresses = '*'
wal_level = hot_standby
max_wal_senders = 10
max_connections=100
checkpoint_segments = 8
wal_keep_segments = 8
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/archive/%f'
Run Code Online (Sandbox Code Playgroud)
这是在备用服务器上失败的命令:
pg_basebackup -h ${MASTER_PORT_5432_TCP_ADDR} -D ${PGDATA} -U ${REP_USER} -vPw --xlog-method=stream
Run Code Online (Sandbox Code Playgroud)
我不明白为什么会发生这种情况。
我可以从 JSON 数据类型创建 VIEW 但将其作为关系结构吗?
例子:
SELECT *
FROM json_test;
Run Code Online (Sandbox Code Playgroud)
结果
[
{
"name": "Roy",
"Country": "USA",
"hobby": "Swim",
"address": "Church Street",
"sex": "M"
},
{
"name": "Roy",
"Country": "USA",
"hobby": "Cricket",
"address": "Amsterdam",
"sex": "F"
},
{
"name": "Anam",
"country": "Greece",
"hobby": "Polo",
"address": "MG Road",
"sex": "M"
}
]
Run Code Online (Sandbox Code Playgroud)
然后创建 VIEW 将类似于(不确定是否/如何执行此操作)
CREATE VIEW normalized AS
SELECT name, country, hobby, address, sex
FROM JSON data
Run Code Online (Sandbox Code Playgroud)
然后我可以用这样的东西查询视图
SELECT *
FROM normalized
Run Code Online (Sandbox Code Playgroud)
结果集
name | country | hobby | address …Run Code Online (Sandbox Code Playgroud) 假设一个简单的查询:
(SELECT MAX(timestamp) FROM events e WHERE e.id < some_id)
+ ((SELECT MIN(timestamp) FROM events e WHERE e.id > some_id)
- (SELECT MAX(timestamp) FROM events e WHERE e.id < some_id)) / 2
Run Code Online (Sandbox Code Playgroud)
如果 some_id是参数,它会根据某些事件序列找到近似时间戳(它采用前一个和后一个事件并平均它们的时间戳)。
这个查询很好用,现在我想把它打包成一个函数:
CREATE FUNCTION id_to_timestamp(integer) RETURNS timestamp with time zone AS
$BODY$
(SELECT MAX(timestamp) FROM events e WHERE e.id < $1)
+ ((SELECT MIN(timestamp) FROM events e WHERE e.id > $1)
- (SELECT MAX(timestamp) FROM events e WHERE e.id < $1)) / 2
$BODY$
LANGUAGE sql; …Run Code Online (Sandbox Code Playgroud) 我想在 PostgreSQL 数据库中保存年份 - 只是年份。我应该如何创建这个字段?有很多关于如何从日期字段中提取年份的信息,但没有关于我应该如何设置仅使用年份的表格的信息。我试过这个:
CREATE TABLE information (
id serial PRIMARY KEY,
year date NOT NULL
);
INSERT INTO "information" ("year") VALUES (2010);
Run Code Online (Sandbox Code Playgroud)
但这失败了:
ERROR: invalid input syntax for type date: "2010"
Run Code Online (Sandbox Code Playgroud) 我在 Ubuntu 14.04 上从源代码安装了 postgresql(我之前也从存储库安装过,我现在只想感受一下它们,因为我将严重依赖这个数据库)。因此,当我从源代码安装时,在我的 postgresql.conf 中,我指定我希望 postmaster 可执行文件中的所有标准错误都转到 /var/log:
log_destination = 'stderr'
logging_collector = on
log_directory = '/var/log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
Run Code Online (Sandbox Code Playgroud)
我知道只有 root 可以写入 /var/log(这是 Ubuntu 上的默认设置),那么人们是如何做到这一点的呢?如何在该日志文件存在之前使其可写?还是人们先手动创建日志文件然后更改其权限?
不幸的是,我的临时解决方案是对 log_filename 的文件名进行硬编码,例如 postgresql-9.4.2-main.log,然后以 root 身份在 /etc/log 中创建该文件,然后将其所有权更改为 postgres,然后当我启动服务器它工作正常。但我希望日志文件是动态的。在达到指定大小后,我希望将旧的压缩起来,并使用当前日期和时间创建一个新的。
我有一个 Java/JDBC 程序,它获取一个示例文件并将数据导入数据库,将其分解为多个关系。该程序针对几种不同的表示多次执行此操作,其中一种使用大对象。我可以分享这些表示的更多细节,但它们很长并且与这个问题无关,因为我正在寻找一些通用的东西。
我想通过在每次导入后检查数据库的大小来比较这些不同表示的大小。该数据库位于 PostgreSQL 9.4 本地 Windows 服务器实例上,没有其他用户和默认配置。它的唯一目的是进行这个测试。
我最初的计划是这样的:
for each representation {
call VACUUM ANALYZE
record old DB size with SELECT pg_tablespace_size('pg_default');
import data into database
call VACUUM ANALYZE
record new DB size with SELECT pg_tablespace_size('pg_default');
store storage cost as new DB size - old DB size
}
Run Code Online (Sandbox Code Playgroud)
显然这种方法有局限性,但我的期望是对于大文件(~100MB),报告的存储成本应该是合理的近似值。请注意,我使用pg_tablespace_size是为了包含主架构之外的数据的贡献,例如大对象(inpg_catalog.pg_largeobject和pg_catalog.pg_largeobject_metadata)。
我想知道这是否是一种正确的方法,以及是否有更好的方法。我不确定是否VACUUM ANALYZE正确更新了 使用的统计信息pg_tablespace_size,即使它是在同一会话中调用的。如果我可以避免调用VACUUM ANALYZE,也会更好,因为这需要以超级用户身份连接才能运行pg_catalog关系。
有什么想法吗?
我正在使用 postgresql 9.3。如果我想添加以下步骤并将这些步骤作为例程调用,使用函数或存储过程会更好吗?
我的基本步骤是:
RENAME TABLE FOOBAR_1234.table1_org TO FOOBAR_1234.table1_old;
DELETE FOOBAR_1234.table1_old WHERE 1=1;
RENAME TABLE FOOBAR_1234.table1 TO FOOBAR_1234.table1_org;
Run Code Online (Sandbox Code Playgroud)
我还需要像1234使用任何 ID一样灵活地参数化ID,例如5678。
如果你有一个例子,那也会有帮助。
postgresql ×10
backup ×1
datatypes ×1
date-format ×1
functions ×1
index ×1
jdbc ×1
json ×1
logs ×1
nosql ×1
performance ×1
upsert ×1
view ×1