使用 PostgreSQL 9.5 我想确保当我运行一个SELECT语句时我得到一致的结果,即如果表在SELECT运行时被修改,我想获得SELECT启动时有效的状态。
基本上,它就像:拍摄一张表的快照,并且在拍摄快照时不允许更新表,然后交付快照,同时再次允许更新。
如果我正确理解隔离级别,REPEATABLE READ这就是我要找的,不是吗?
现在我的问题是:如何SELECT使用REPEATABLE READ隔离级别运行?或者我错过了什么,我的方法是错误的?我将如何解决这个问题?
postgresql select isolation-level snapshot-isolation postgresql-9.5
每当我使用 UUID 作为文字时,我都会得到
SELECT a82857b6-e336-4c6c-8499;
ERROR: syntax error at or near "-"
Run Code Online (Sandbox Code Playgroud)
我认为这可能是编码问题,但似乎并非如此。
我在从不同主机连接到 PostgreSQL 服务器时遇到错误,我配置了两者postgresql.conf,pg_hba.conf 但不幸的是没有结果。
所以我已经从包中在 Debian 上安装了 PostgreSQL,添加了用户createuser和useradd,然后通过createdb作为我的自定义用户作为所有者创建了 db 。之后我设置postgresql.conf了这些值
listen_addresses = '*'
ssl = false
Run Code Online (Sandbox Code Playgroud)
并添加了这一行 pg_hba.conf
host all all 192.168.0.0/24 md5
Run Code Online (Sandbox Code Playgroud)
然后我重新启动了服务并尝试通过我的机器连接psql -U admin -d admin -h 10.10.30.88,我收到此错误
psql: FATAL: no pg_hba.conf entry for host "192.168.10.195", user "admin", database "admin", SSL off
Run Code Online (Sandbox Code Playgroud)
那么我是不是忘记了什么?
所有的 pg_hba.conf
local all postgres peer
local all all peer
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all …Run Code Online (Sandbox Code Playgroud) 我有一个相当标准的餐厅模型,restaurant在 PostgreSQL 数据库中有一张桌子。所有餐厅都有评分(由average、vote_count和组成vote_sum),但为了避免重复此评分模式,例如pictures我将它们移到单独的rating表中并仅存储rating_idin restaurant。
我知道 1 个评级只会被整个数据库中的 1 个其他行使用。rating在restaurant或 中删除行时如何级联删除picture?
我一直在环顾四周,但我能找到的只是设置了 a REFERENCES,但为此我需要知道将删除哪些表数据。
我知道触发器可以完成这项工作,我只是希望有更优雅的东西。
我使用 Postgresql 9.4,我有一个名为 foo 的大表。我想搜索它,但如果搜索文本很短(例如“v”)或很长(例如“这是一个在表 foo% 上使用 gin 的搜索示例”),我的执行时间会很长。在这种情况下,我的索引被忽略。这是我的搜索查询:
EXPLAIN (ANALYZE, TIMING)
SELECT "foo".* FROM "foo" WHERE "foo"."locale" = 'de'
AND f_unaccent(foo.name) ILIKE f_unaccent('v%')
AND foo.configuration->'bar' @> '{"is":["a"]}'
LIMIT 100;
Run Code Online (Sandbox Code Playgroud)
这是我的索引:
CREATE INDEX index_foo_on_name_de_gin ON foo USING gin(f_unaccent(name) gin_trgm_ops) WHERE locale = 'de';
Run Code Online (Sandbox Code Playgroud)
为什么索引被忽略并使用seq scan和/或Bitmap heap scan?如何添加其他索引来解决此问题?
为什么它会重新检查?
Recheck Cond: ((f_unaccent((name)::text) ~~* 'v%'::text) AND ((locale)::text = 'de'::text))
Run Code Online (Sandbox Code Playgroud)
功能f_unaccent:
CREATE OR REPLACE FUNCTION f_unaccent(text)
RETURNS text AS
$func$
SELECT unaccent('unaccent', $1)
$func$ LANGUAGE sql IMMUTABLE …Run Code Online (Sandbox Code Playgroud) postgresql performance index index-tuning postgresql-9.4 postgresql-performance
我有一个包含数百万行的表,分为几个类别(比如数字 1-5)。访问数据库的应用程序使用一个单一的数据库帐户。但是,该应用程序有自己的用户帐户,每个应用程序用户只能访问某些类别。因此,允许的类别列表通过会话变量传递给数据库:
SET SESSION mydb.allowed_categories = '1,3,5';
Run Code Online (Sandbox Code Playgroud)
我使用 RLS 根据会话变量过滤行:
CREATE POLICY table_select_policy ON big_table
FOR SELECT
USING (ARRAY[category] && string_to_array(current_setting('mydb.allowed_categories'),',')::int[]));
Run Code Online (Sandbox Code Playgroud)
问题在于,使用这种方法,RLS 行过滤需要花费大量时间。另一方面,当我通过以下方式进行实验时:
CREATE POLICY table_select_policy ON big_table
FOR SELECT
USING (category = 1 OR category = 3 OR category = 5);
Run Code Online (Sandbox Code Playgroud)
RLS 过滤几乎快了 10 倍。当然,这种硬编码是行不通的,因为我想在应用程序中动态更改允许的类别列表。
这 category列有一个 btree 索引,但是由于类别的数量相当少,查询计划器总是倾向于对 RLS 过滤器进行顺序扫描。
所以我的问题是 - 有没有办法优化 RLS 表达式,使其至少更接近硬编码方法?你会建议一个不同的解决方案吗?该应用程序有很多用户,所以我不想为每个用户都创建一个数据库帐户。
我正在尝试使用相同的键字段对多个表执行 INSERT。根据序列操作函数:
重要提示:由于序列是非事务性的,如果事务回滚,则 setval 所做的更改不会撤消。
以上让我担心在我的交易过程中其他东西可能会更新序列。
所以这是我当前的查询:
BEGIN;
--[other queries and stuff here]
CREATE TEMPORARY TABLE my_temp_table ON COMMIT DROP AS
SELECT
(SETVAL('seq_A',(SELECT "last_value" FROM seq_A) + COUNT(*) OVER ()) - (ROW_NUMBER() OVER (ORDER BY some_other_table.field1 DESC))) AS primarykeyid,
some_other_table.morefields
FROM
some_other_table;
--[INSERTs into multiple different tables with primarykeyid here]
COMMIT;
Run Code Online (Sandbox Code Playgroud)
是否SETVAL被调用一次中的每一行my_temp_table或者它被调用一次?
在创建之前进行单独的查询以my_temp_table在运行之前“保留”值会更好吗?例如:
BEGIN;
--[other queries and stuff here]
CREATE TEMPORARY TABLE my_temp_sequence_value ON COMMIT DROP AS
SELECT
(SETVAL('seq_A',(SELECT "last_value" FROM seq_A) …Run Code Online (Sandbox Code Playgroud) 我试图在 Postgres 9.4 中加速这个查询:
SELECT "groupingsFrameHash", COUNT(*) AS nb
FROM "public"."zrac_c1e350bb-a7fc-4f6b-9f49-92dfd1873876"
GROUP BY "groupingsFrameHash"
HAVING COUNT(*) > 1
ORDER BY nb DESC LIMIT 10
Run Code Online (Sandbox Code Playgroud)
我在 上有一个索引"groupingsFrameHash"。我不需要精确的结果,模糊近似就足够了。
这是查询计划:
Limit (cost=17207.03..17207.05 rows=10 width=25) (actual time=740.056..740.058 rows=10 loops=1)
-> Sort (cost=17207.03..17318.19 rows=44463 width=25) (actual time=740.054..740.055 rows=10 loops=1)
Sort Key: (count(*))
Sort Method: top-N heapsort Memory: 25kB
-> GroupAggregate (cost=14725.95..16246.20 rows=44463 width=25) (actual time=615.109..734.740 rows=25977 loops=1)
Group Key: "groupingsFrameHash"
Filter: (count(*) > 1)
Rows Removed by Filter: 24259
-> Sort (cost=14725.95..14967.07 rows=96446 …Run Code Online (Sandbox Code Playgroud) 我有一个表,其中一列是自动递增序列号。我也希望将相同的值存储在另一列中(以便以后可以更改)。
我的表结构是这样的:
CREATE TABLE Test
(
test_id integer NOT NULL DEFAULT nextval('test_id_seq'::regclass),
...
...
uid integer not null DEFAULT currval('test_id_seq'::regclass),
)
Run Code Online (Sandbox Code Playgroud)
我想要uid = test_id但问题是在一个会话中插入多行时。然后currval不采取正确的ID。
我不想使用触发器。我该如何管理?
我通常在我的数据库上进行这个查询
SELECT * FROM Example_tab WHERE Column_a + Column_b < 10;。
是否可以创建基于Column_a + Column_b < 10加速此查找的索引。我认为可以在此处为基于 oracle 的数据库执行此操作(通过执行CREATE INDEX Idx ON Example_tab(Column_a + Column_b);)。但我无法在任何地方为 postgresql 或 mysql 找到它。
甚至可以在 oracle 以外的数据库上执行此操作吗?如果是,它是否记录在某处,它们叫什么(基本上,我应该用什么 google 找到它们)?
在此先感谢您的帮助。
postgresql ×10
index ×3
performance ×2
cascade ×1
connectivity ×1
constraint ×1
count ×1
delete ×1
index-tuning ×1
mysql ×1
optimization ×1
security ×1
select ×1
sequence ×1
syntax ×1
uuid ×1