我注意到我的一个 SQL 查询比我预期的要慢得多,结果查询计划程序提出了一个对我来说似乎很糟糕的计划。我的查询如下所示:
select A.style, count(B.x is null) as missing, count(*) as total
from A left join B using (id, type)
where A.country_code in ('US', 'DE', 'ES')
group by A.country_code, A.style
order by A.country_code, total
Run Code Online (Sandbox Code Playgroud)
B 有一个 (type, id) 索引,A 有一个 (country_code, style) 索引。A 比 B 小得多:A 中有 250K 行,B 中有 100M。
所以,我希望查询计划看起来像:
country_code(type, id)索引查找匹配行(如果有)country_code和分组事物style但是查询规划器决定执行此操作的最佳方法是对 B 进行顺序扫描,然后对 A 进行右连接。我无法理解为什么会这样;有没有人有想法?这是它生成的实际查询计划:
Sort (cost=14283513.27..14283513.70 rows=171 width=595)
Sort Key: a.country_code, …Run Code Online (Sandbox Code Playgroud) 经过对我的一个查询(Postgres)的几次测试后,我意识到通过设置enable_seqscan=关闭,查询占用原始时间的1/3(使用psql控制台完成EXPLAIN ANALYZE)
由于不建议为整个服务器更改此设置,因此我想将其设置为OFF仅用于此查询.
我该怎么做?可能吗?
我的实现基于框架Kohana(PHP),它使用DB对象(DB :: select)来执行查询.
我在CentOS Linux上的postgres是8.4.9.
我在PostgreSQL(9.5.1)中有以下查询:
select e.id, (select count(id) from imgitem ii where ii.tabid = e.id and ii.tab = 'esp') as imgs,
e.ano, e.mes, e.dia, cast(cast(e.ano as varchar(4))||'-'||right('0'||cast(e.mes as varchar(2)),2)||'-'|| right('0'||cast(e.dia as varchar(2)),2) as varchar(10)) as data,
pl.pltag, e.inpa, e.det, d.ano anodet, coalesce(p.abrev,'')||' ('||coalesce(p.prenome,'')||')' determinador, d.tax, coalesce(v.val,v.valf)||' '||vu.unit as altura,
coalesce(v1.val,v1.valf)||' '||vu1.unit as DAP, d.fam, tf.nome família, d.gen, tg.nome gênero, d.sp, ts.nome espécie, d.inf, e.loc, l.nome localidade, e.lat, e.lon
from esp e
left join det d on e.det = d.id
left join tax tf …Run Code Online (Sandbox Code Playgroud) postgresql performance pattern-matching query-performance postgresql-performance
我有一个由 Hibernate 为 JBPM 生成的复杂查询。我无法真正修改它,我正在寻找尽可能优化它。
我发现 ORDER BY DESC 比 ORDER BY ASC 慢得多,你有什么想法吗?
PostgreSQL 版本:9.4 架构:https://pastebin.com/qNZhrbef 查询:
select
taskinstan0_.ID_ as ID1_27_,
taskinstan0_.VERSION_ as VERSION3_27_,
taskinstan0_.NAME_ as NAME4_27_,
taskinstan0_.DESCRIPTION_ as DESCRIPT5_27_,
taskinstan0_.ACTORID_ as ACTORID6_27_,
taskinstan0_.CREATE_ as CREATE7_27_,
taskinstan0_.START_ as START8_27_,
taskinstan0_.END_ as END9_27_,
taskinstan0_.DUEDATE_ as DUEDATE10_27_,
taskinstan0_.PRIORITY_ as PRIORITY11_27_,
taskinstan0_.ISCANCELLED_ as ISCANCE12_27_,
taskinstan0_.ISSUSPENDED_ as ISSUSPE13_27_,
taskinstan0_.ISOPEN_ as ISOPEN14_27_,
taskinstan0_.ISSIGNALLING_ as ISSIGNA15_27_,
taskinstan0_.ISBLOCKING_ as ISBLOCKING16_27_,
taskinstan0_.LOCKED as LOCKED27_,
taskinstan0_.QUEUE as QUEUE27_,
taskinstan0_.TASK_ as TASK19_27_,
taskinstan0_.TOKEN_ as TOKEN20_27_,
taskinstan0_.PROCINST_ as PROCINST21_27_, …Run Code Online (Sandbox Code Playgroud) 我正在使用 Postgres 9.2.24。
我有一个以_order大约 100,000,000 行命名的表。该表有一个名为 的列merged_id int8。大约 2,000,000_order行有一个merged_id值,其余的为空。
我找到了两种不同的 Postgres 行为,我在其中_order使用查询进行搜索
select * from _order where merged_id in ( 10001 ,10002 ,10003 ....., 11000);
Run Code Online (Sandbox Code Playgroud)
如果我创建这样的索引:
create index order_merged_id_index on _order(merged_id);
Run Code Online (Sandbox Code Playgroud)
无论 in 子句中有多少个 id(测试从 1 到 50 到 100 到 200 到 1000)EXPLAIN显示搜索都将使用index_scan.
但是如果我创建这个部分索引:
create index order_merged_id_index on _order(merged_id) where merged_id is not null;
Run Code Online (Sandbox Code Playgroud)
EXPLAINseq_scan在WHERE子句中显示100 多个 ID 号。
为什么是这样?
有什么办法可以解决吗?
我正在使用Postgres 9.3.
我有两张桌子T1 和它们之间T2的n:m关系T1_T2_rel.现在我想创建一个视图,除了T1的列之外,还提供了一个列,对于T1中的每个记录,该列包含一个数组,其中包含T2的所有相关记录的主键ID.如果T2中没有相关条目,则该列的相应字段应包含空值.
我的架构的抽象版本如下所示:
CREATE TABLE T1 ( t1_id serial primary key, t1_data int );
CREATE TABLE T2 ( t2_id serial primary key );
CREATE TABLE T1_T2_rel (
t1_id int references T1( t1_id )
, t2_id int references T2( t2_id )
);
Run Code Online (Sandbox Code Playgroud)
相应的样本数据可以生成如下:
INSERT INTO T1 (t1_data)
SELECT cast(random()*100 as int) FROM generate_series(0,9) c(i);
INSERT INTO T2 (t2_id) SELECT nextval('T2_t2_id_seq') FROM generate_series(0,99);
INSERT INTO T1_T2_rel
SELECT cast(random()*10 as int) % 10 + …Run Code Online (Sandbox Code Playgroud) 当表较小时,此查询具有合理的时间。我正在尝试确定什么是瓶颈,但是我不确定如何分析EXPLAIN结果。
SELECT
COUNT(*)
FROM performance_analyses
INNER JOIN total_sales ON total_sales.id = performance_analyses.total_sales_id
WHERE
(size > 0) AND
total_sales.customer_id IN (
SELECT customers.id FROM customers WHERE customers.active = 't'
AND customers.visible = 't' AND customers.organization_id = 3
) AND
total_sales.product_category_id IN (
SELECT product_categories.id FROM product_categories
WHERE product_categories.organization_id = 3
) AND
total_sales.period_id = 193;
Run Code Online (Sandbox Code Playgroud)
我已经尝试了INNER JOIN'ing customers和product_categories表的方法以及执行INNER SELECT的方法。两者有相同的时间。
这是EXPLAIN的链接:https : //explain.depesz.com/s/9lhr
Postgres版本:
x86_64-unknown-linux-gnu上的PostgreSQL 9.4.5,由gcc(GCC)4.8.2 20140120(Red Hat 4.8.2-16)编译,64位
表和索引:
CREATE TABLE total_sales (
id serial …Run Code Online (Sandbox Code Playgroud) postgresql ×7
indexing ×4
sql ×4
performance ×3
count ×1
hibernate ×1
optimization ×1
php ×1
settings ×1
sql-in ×1
sql-order-by ×1