我不清楚 IMMUTABLE、VOLATILE 和 STABLE 函数定义中的真正含义。
我阅读了文档,特别是每个文档的定义。
IMMUTABLE 表示函数不能修改数据库并且 在给定相同的参数值时总是返回相同的结果;也就是说,它不进行数据库查找或以其他方式使用不直接出现在其参数列表中的信息。如果给出了这个选项,任何带有全常量参数的函数调用都可以立即替换为函数值。
STABLE 表示该函数不能修改数据库,并且在单个表扫描中,对于相同的参数值,它将始终返回相同的结果,但其结果可能会在 SQL 语句之间发生变化。对于结果取决于数据库查找、参数变量(例如当前时区)等的函数,这是合适的选择。(对于希望查询由当前命令修改的行的 AFTER 触发器是不合适的。)另请注意, current_timestamp 系列函数被认为是稳定的,因为它们的值在事务中不会改变。
VOLATILE 表示即使在单个表扫描中函数值也可以更改,因此无法进行优化。从这个意义上说,相对较少的数据库函数是易变的;一些例子是 random()、currval()、timeofday()。但请注意,任何具有副作用的函数都必须归类为 volatile,即使其结果是可预测的,以防止调用被优化掉;一个例子是 setval()。
我的困惑来自与不可改变的条件,稳定的功能总是或始终返回相同的结果给出了相同的论点。
IMMUTABLE 定义声明该函数不进行数据库查找或以其他方式使用未直接出现在其参数列表中的信息。所以,对我来说,这意味着这些函数用于操作客户端提供的数据,并且不应该有 SELECT 语句......尽管这对我来说听起来有点奇怪。
对于 STABLE,定义类似,因为它说它应该始终如一地返回相同的结果。所以,对我来说,这意味着每次使用相同的参数调用函数时,它都应该返回相同的结果(每次都返回相同的行)。
所以,对我来说......这意味着任何对一个或多个可以更新的表执行 SELECT 的函数应该只是易失性的。
但是,再一次……这对我来说听起来不对。
回到我的用例,我正在编写在不断添加的表上执行带有多个 JOIN 的 SELECT 语句的函数,因此函数调用预计每次调用时都会返回不同的结果,即使使用相同的参数.
那么,这是否意味着我的函数应该是 VOLATILE?即使文档表明相对较少的数据库函数在这个意义上是易变的?
谢谢!
我看到其他问题的答案是否定的(即索引不会随标准转移pg_restore)。但是,它看起来像在我最近的转储/恢复中一样,我不确定它是否真的转移了。
我将我的数据库从 PostgreSQL 9.3 迁移到 9.4.5 并使用转储/恢复来这样做。
下面是使用的命令:
sudo -u postgres pg_dump -h localhost -p 5432 -d nominatim -F d -f dump/postgres/backup -j 20
sudo -u postgres pg_restore --create --dbname=nominatim --exit-on-error -h localhost -p 5432 -F d -j 7 dump/postgres/backup
Run Code Online (Sandbox Code Playgroud)
转储和恢复成功(没有错误)。
我在进行恢复时将 autovacuum 设置为关闭,因此我analyze从 psql 中运行(无参数)并连接到已恢复的数据库。
我注意到的第一件事是,在 9.3 下,数据目录占用了大约 860GB,而在 9.4 下,它占用了大约 680GB。9.4 是不是更高效?
我注意到的第二件事是我看到了数据库中的索引:
nominatim=# \d country_name
Table "public.country_name"
Column | Type | Modifiers
-------------------------------+---------------------------------
country_code | character varying(2) |
name | hstore |
country_default_language_code …Run Code Online (Sandbox Code Playgroud) 我有一个大型(> 700GB)PostgreSQL 数据库。我正在将其导入 AWS RDS。我意识到有些模块会导致问题,我们正在单独处理这些问题,所以现在,我只是致力于将数据迁移到 RDS。
我正在使用 pg_dump 和 pg_restore 9.4.5 来回迁移 PostgreSQL 9.4.5。
传输几个小时后(pg_dump 到 pg_restore 与目录格式),我检查了日志并意识到有一件我不知道的 Postgres 用户拥有的东西(可能是一张表?)。
我在 toc.dat 文件中找到了进行调用的行并解压了 .dat.gz 文件,发现它只包含“\”。(无引号)在其中。
所以,我的问题是,除了停止传输并重新开始之外,有没有一种方法可以在导入完成后简单地传输该特定命令和文件?
以下是相关详情。
pg_dump 命令:
pg_dump -h localhost -p 5432 -d DBNAME -U USERNAME -F d -f /mnt/backup -j 7
Run Code Online (Sandbox Code Playgroud)
pg_restore 命令:
pg_restore --dbname=DBNAME --no-tablespaces --host=HOSTNAME --port=5432 --username=USERNAME --verbose -F d -j 6 /mnt/backup
Run Code Online (Sandbox Code Playgroud)
toc.dat 文件中的部分。我意识到目录格式以二进制格式输出,但我希望这是可识别的这一事实意味着有一种方法可以返回并修复该错误。
^@^F^@^@^@public^A^A^@^@^@^@^H^@^@^@postgres^@^E^@^@^@false^@^C^@^@^@173^A^A^@^@^@^@ ^@^@^@10393.dat^@W<^@^@^@^A^@^@^@^@^A^@^@^@0^@^E^@^@^@26106^@^N^@^@^@search_name_66^@
^@^@^@TABLE DATA^@^C^@^@^@^@^@^@^@^@^@^@^@^@^@^@]^@^@^@COPY search_name_66 (place_id, search_rank, address_rank, name_vector, centroid) FROM stdin;
Run Code Online (Sandbox Code Playgroud)
pg_restore 报告的实际错误:
pg_restore: [archiver (db)] Error from TOC …Run Code Online (Sandbox Code Playgroud)