在 PostgreSQL 中,我的表上的日期字段有一个索引tickets。当我将字段与 进行比较时now(),查询非常有效:
# explain analyze select count(1) as count from tickets where updated_at > now();
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=90.64..90.66 rows=1 width=0) (actual time=33.238..33.238 rows=1 loops=1)
-> Index Scan using tickets_updated_at_idx on tickets (cost=0.01..90.27 rows=74 width=0) (actual time=0.016..29.318 rows=40250 loops=1)
Index Cond: (updated_at > now())
Total runtime: 33.271 ms
Run Code Online (Sandbox Code Playgroud)
now()如果我尝试将其与负间隔进行比较,它会走下坡路并使用位图堆扫描。
# explain analyze select count(1) as count from tickets where updated_at > (now() - '24 hours'::interval);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=180450.15..180450.17 rows=1 width=0) …Run Code Online (Sandbox Code Playgroud) sql postgresql indexing sql-execution-plan postgresql-performance
有一个表和一个gin索引,插入1,000,000个随机数。0 < 数量 < 100,000。
测试两个等效查询
create table Test
(
id serial primary key,
code varchar(255) not null
);
create index Test_code_gin on Test using gin (code gin_trgm_ops);
-- Test1
explain analyse
select * from Test where code like '1234';
-- Test2
explain analyse
select * from Test where code = '1234';
Run Code Online (Sandbox Code Playgroud)
测试1使用gin_trgm_ops索引,执行时间:1.640 ms;
Test2不使用索引,执行时间:24.531 ms;
我该怎么做才能让 PostgreSQL 使用索引?或者修改ORM策略和我的SQL语句?或者干脆添加一个BTree索引?
之前可能已经提出过这个问题,但谷歌搜索"IN"这样的关键字效果不佳.
这是我的查询:
UPDATE tblCustomer SET type = 2
WHERE idcustomer
IN (SELECT fidcustomer1
FROM tblorder
UNION
SELECT fidcustomer2
FROM tblorder
)
Run Code Online (Sandbox Code Playgroud)
要打破它:我想将所有客户的类型(只是一个int)设置为2,对于出现在order-table中的所有客户,在任一列中.
在我的测试数据中,这些表中没有一行包含超过几百行,但查询运行了很多分钟(即使没有UNION,这似乎没有太大区别),显然重新执行内部查询客户每行一次.我显然可以将它重写为单个SELECT DISTINCT(id),然后进行几百个单行更新,并以我用于ODBC访问的任何语言执行逻辑,但这只是一个黑客攻击.
我怎样才能正确地重写这个?
附录:我要更新的表包含很多相对较大的BYTEA blob,每行几MB.它们被设置为Storage External或Extended,但我想知道这是否会使顺序扫描变慢.所有更新似乎都需要很长时间,而不仅仅是这一次.
我需要帮助优化PostgreSQL查询,该查询使用BETWEEN带有timestamp字段的子句.
我有2张桌子:
ONE(int id_one(PK), datetime cut_time, int f1 . . .)
Run Code Online (Sandbox Code Playgroud)
包含大约3394行
TWO(int id_two(PK), int id_one(FK), int f2 . . .)
Run Code Online (Sandbox Code Playgroud)
包含大约4000000行
有两个的PK B树索引id_one和id_two,在FK id_one和cut_time.
我想执行如下查询:
select o.id_one, Date(o.cut_time), o.f1, t.f2
from one o
inner join two t ON (o.id_one = t.id_one)
where o.cut_time between '2013-01-01' and '2013-01-31';
Run Code Online (Sandbox Code Playgroud)
此查询在大约7秒内检索大约1.700.000行.
报告分析报告下面报告:
"Merge Join (cost=20000000003.53..20000197562.38 rows=1680916 width=24) (actual time=0.017..741.718 rows=1692345 loops=1)"
" Merge Cond: (c.coilid = hf.coilid)"
" -> Index Scan …Run Code Online (Sandbox Code Playgroud) 我们在RedHat中使用Postgres 9.2.我们有一个类似于以下的表:
CREATE TABLE BULK_WI (
BULK_ID INTEGER NOT NULL,
USER_ID VARCHAR(20) NOT NULL,
CHUNK_ID INTEGER,
STATE VARCHAR(16),
CONSTRAINT BASE_BULK_WI_PK PRIMARY KEY(BULK_ID,USER_ID)
);
CREATE INDEX BASE_BULK_WI_IDX01 ON BULK_WI(STATE, CHUNK_ID);
Run Code Online (Sandbox Code Playgroud)
作为批处理作业的一部分,我们首先使用新的BULK_ID向表中添加许多行.所有新记录都有CHUNK_ID = NULL,STATE ='PENDING'.插入物在500K和1.5M行之间.发生这种情况时,表的大小超过15M记录.
在插入之后,我们开始以块的形式处理表.为此,我们首先为下一个块选择一些项目,然后处理它们.使用以下查询选择项目:
UPDATE BASE_BULK_WI wi SET wi.STATE = 'PROCESSING', wi.CHUNK_ID = $1
WHERE wi.STATE='PENDING' AND wi.BULK_ID = $2
AND wi.USER_ID IN
(SELECT USER_ID FROM BASE_BULK_WI WHERE BULK_ID = $3
AND CHUNK_ID IS NULL AND STATE='PENDING' LIMIT $4 FOR UPDATE)
Run Code Online (Sandbox Code Playgroud)
每次块迭代增加$ 1,$ 2和$ 3 …
sql postgresql batch-processing postgresql-9.2 postgresql-performance
CREATE TABLE product (
product_id SERIAL,
factory_key VARCHAR(60),
relevant BOOLEAN
)
Indexes:
"product_factory_key_key" btree (factory_key);
"product_factory_key_relevant_key" btree (factory_key, relevant) WHERE relevant = false;
"product_relevant_key" btree (relevant);
Run Code Online (Sandbox Code Playgroud)
事实:
product表中有大约1亿条记录这是问题查询:
SELECT * FROM product WHERE factory_key='some_product_key' AND relevant=false LIMIT 10;
Run Code Online (Sandbox Code Playgroud)
解释分析:
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.00..23.06 rows=10 width=188) (actual time=2709.654..32252.961 rows=10 loops=1)
-> Seq Scan on product (cost=0.00..7366785.34 rows=3194759 width=188) (actual time=2709.634..32252.904 rows=10 loops=1)
Filter: ((NOT relevant) AND ((product_key)::text = 'some_product_key'::text))
Rows Removed by Filter: …Run Code Online (Sandbox Code Playgroud) 对于PostgreSQL,我想在三列上使用复合索引A, B, C。B是created_at日期时间,有时我可能不带进行查询B。
如果我在上复合索引,(A, B, C)然后在A和上查询条件C,但没有,该B怎么办?(也就是说,A而C但希望它在所有的时候,不只是一些特定的时间范围?)
Postgres是否足够聪明,仍然可以使用(A, B, C)复合索引而只跳过B?
有人可以解释这三个查询之间的性能差异吗?
concat() 功能:
explain analyze
select * from person
where (concat(last_name, ' ', first_name, ' ', middle_name) like '%???%');
Seq Scan on person (cost=0.00..4.86 rows=1 width=15293) (actual time=0.032..0.140 rows=6 loops=1)
Filter: (pg_catalog.concat(last_name, ' ', first_name, ' ', middle_name) ~~ '%???%'::text)
Total runtime: 0.178 ms
Run Code Online (Sandbox Code Playgroud)
SQL标准串联||:
explain analyze
select * from person
where ((last_name || ' ' || first_name || ' ' || middle_name) like '%???%');
Seq Scan on person (cost=0.00..5.28 rows=1 width=15293) (actual time=0.023..0.080 rows=6 loops=1)
Filter: ((((((last_name)::text …Run Code Online (Sandbox Code Playgroud) sql postgresql concatenation pattern-matching postgresql-performance
我们有一个超过62k行的表.我们正在运行一个非常简单的删除查询,需要45分钟才能完成:
DELETE FROM myTable WHERE createdtime < '2017-03-07 05:00:00.000'
Run Code Online (Sandbox Code Playgroud)
我们尝试过的事情:
1-在timestamp列上添加了一个索引,但没有帮助.
2-使用函数分批删除20或50行,这仍然非常慢.
3-删除引用此表及其自己的主键约束的所有外键约束,这有助于将时间减少到几秒但我们无法在生产数据库上安全地执行此操作,因为它将锁定表并防止读取并在事务运行时写入.
我拒绝相信这个查询通常需要很长时间才能完成.任何建议表示赞赏.
I would like to bulk-INSERT/UPSERT a moderately large amount of rows to a postgreSQL database using R. In order to do so I am preparing a multi-row INSERT string using R.
query <- sprintf("BEGIN;
CREATE TEMPORARY TABLE
md_updates(ts_key varchar, meta_data hstore) ON COMMIT DROP;
INSERT INTO md_updates(ts_key, meta_data) VALUES %s;
LOCK TABLE %s.meta_data_unlocalized IN EXCLUSIVE MODE;
UPDATE %s.meta_data_unlocalized
SET meta_data = md_updates.meta_data
FROM md_updates
WHERE md_updates.ts_key = %s.meta_data_unlocalized.ts_key;
COMMIT;", md_values, schema, schema, schema, schema)
DBI::dbGetQuery(con,query)
Run Code Online (Sandbox Code Playgroud)
The entire function can be …
postgresql ×10
sql ×5
indexing ×4
between ×1
copy ×1
foreign-keys ×1
insert ×1
pg-trgm ×1
r ×1
sql-delete ×1
union ×1