在Postgres数据库中,我正在查询MY_DATE具有3亿行的大型表中的不同值。它们大约有400个,并且该列MY_DATE已建立索引。
Select distinct MY_DATE from MY_TABLE;
Run Code Online (Sandbox Code Playgroud)
查询运行22分钟。
在Oracle数据库上具有完全相同的数据集和相同的索引定义的相同查询运行11秒。
查询计划显示查询正在使用索引:
EXPLAIN Select distinct MY_DATE from MY_TABLE LIMIT 200;
Run Code Online (Sandbox Code Playgroud)
给出:
QUERY PLAN
Limit (cost=0.57..7171644.14 rows=200 width=8)
-> Unique (cost=0.57..15419034.24 rows=430 width=8)
-> Index Only Scan using idx_obsdate on my_table (cost=0.57..14672064.14 rows=298788038 width=8)
Run Code Online (Sandbox Code Playgroud)
当我限制结果时,查询会变得更快。例如
Select distinct MY_DATE from MY_TABLE LIMIT 5;
Run Code Online (Sandbox Code Playgroud)
在不到几秒的时间内运行。
但:
Select distinct MY_DATE from MY_TABLE LIMIT 50;
Run Code Online (Sandbox Code Playgroud)
已经花了几分钟。该LIMIT子句的时间似乎成倍增加。
我希望Postgres查询能够像OracleDB一样在几秒钟内运行。索引扫描(即使是一张大桌子)也需要20分钟才能完成。
有什么建议导致问题的原因以及我该怎么办?
我core_message在 Postgres 中有一个表,有数百万行看起来像这样(简化):
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? Colonne ? Type ? Collationnement ? NULL-able ? Par défaut ?
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? id ? integer ? ? not null ? nextval('core_message_id_seq'::regclass) ?
? mmsi ? integer ? ? not null ? ?
? time ? timestamp with time zone ? ? not null ? ?
? point ? geography(Point,4326) ? ? ? ?
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Index:
"core_message_pkey" PRIMARY KEY, btree (id)
"core_message_uniq_mmsi_time" UNIQUE CONSTRAINT, btree (mmsi, "time")
"core_messag_mmsi_b36d69_idx" btree (mmsi, "time" …Run Code Online (Sandbox Code Playgroud) sql postgresql indexing query-optimization greatest-n-per-group
我正在尝试使用同一表中另一行的值更新表中的多个列:
CREATE TEMP TABLE person (
pid INT
,name VARCHAR(40)
,dob DATE
,younger_sibling_name VARCHAR(40)
,younger_sibling_dob DATE
);
INSERT INTO person VALUES (pid, name, dob)
(1, 'John', '1980-01-05'),
(2, 'Jimmy', '1975-04-25'),
(3, 'Sarah', '2004-02-10'),
(4, 'Frank', '1934-12-12');
Run Code Online (Sandbox Code Playgroud)
任务是来填充younger_sibling_name,并younger_sibling_dob用最接近他们年龄的人的姓名和出生的日子,但不是旧的或相同的年龄。
我可以dob轻松设置弟弟妹妹,因为这是确定要与相关子查询一起使用的记录的值(我认为这是一个例子?):
UPDATE person SET younger_sibling_dob=(
SELECT MAX(dob)
FROM person AS sibling
WHERE sibling.dob < person.dob);
Run Code Online (Sandbox Code Playgroud)
我只是看不到任何方法来获得name? 对于每个 MAX 选择
,实际查询将运行大约100 万条记录,每组 100-500 条,因此性能是一个问题。
编辑:
在尝试了许多不同的方法后,我决定采用这种方法,我认为它可以很好地平衡能够用中间结果验证数据,显示逻辑的意图,并充分执行:
WITH sibling AS ( …Run Code Online (Sandbox Code Playgroud) sql postgresql correlated-subquery window-functions sql-update
我尝试将两个具有不同时间分辨率的表合并到最近的日期。
表格如下:
表格1:
id | date | device | value1
----------------------------------
1 | 10:22 | 13 | 0.53
2 | 10:24 | 13 | 0.67
3 | 10:25 | 14 | 0.83
4 | 10:25 | 13 | 0.32
Run Code Online (Sandbox Code Playgroud)
表2:
id | date | device | value2
----------------------------------
22 | 10:18 | 13 | 0.77
23 | 10:21 | 14 | 0.53
24 | 10:23 | 13 | 0.67
25 | 10:28 | 14 | 0.83
26 | 10:31 | …Run Code Online (Sandbox Code Playgroud) 我正在尝试运行一个连接表自身的查询,并进行模糊字符串比较(使用trigram比较)来查找可能的公司名称匹配.我的目标是返回记录,其中一个记录的公司名称(ref_name字段)的三元组相似性与另一个记录的公司名称相匹配.目前,我的阈值设置为0.9,因此它只会返回很可能包含类似字符串的匹配项.
我知道自联接本质上可以导致许多比较,但我想尽我所能地优化我的查询.我不需要即时结果,但是目前我运行的查询需要11个小时才能运行.
我在Ubuntu 12.04服务器上运行Postgres 9.2.我不知道ref_name字段的最大长度(我匹配的字段)是什么,所以我将它设置为a varchar(300).我想知道将它设置为文本类型可能会影响性能,或者是否有更好的字段类型可用于加速性能.我LC_CTYPE和LC_COLLATE语言环境设置为"en_US.UTF-8"
我运行查询的表总共包含大约160万条记录,但运行了11个小时的查询只占一小部分(约100k).
表结构:
CREATE TABLE ref_name (
ref_name_id integer,
ref_name character varying(300),
ref_name_type character varying(2),
name_display text,
load_date timestamp without time zone
)
Run Code Online (Sandbox Code Playgroud)
索引:
CREATE INDEX ref_name_ref_name_trigram_idx ON ref_name
USING gist (ref_name COLLATE pg_catalog."default" gist_trgm_ops);
CREATE INDEX ref_name_ref_name_trigram_idx_1 ON ref_name
USING gist (ref_name COLLATE pg_catalog."default" gist_trgm_ops)
WHERE ref_name_type::text = 'E'::text;
CREATE INDEX ref_name_ref_name_e_idx ON ref_name
USING btree (ref_name COLLATE pg_catalog."default")
WHERE ref_name_type::text = 'E'::text;
Run Code Online (Sandbox Code Playgroud)
查询:
select a.ref_name_id as name_id,a.ref_name …Run Code Online (Sandbox Code Playgroud) 我有以下查询,它为每个查询获取id最新的N :observationsstation
SELECT id
FROM (
SELECT station_id, id, created_at,
row_number() OVER(PARTITION BY station_id
ORDER BY created_at DESC) AS rn
FROM (
SELECT station_id, id, created_at
FROM observations
) s
) s
WHERE rn <= #{n}
ORDER BY station_id, created_at DESC;
Run Code Online (Sandbox Code Playgroud)
我有指标的id,station_id,created_at。
这是我想出的唯一解决方案,每个站可以获取多个记录。但是,它非常慢(81000条记录的表为154.0毫秒)。
如何加快查询速度?
我有一个很难解决的问题,我想你可以帮忙。我有一个包含数百万条记录的表,其中根据注册表值每 10 分钟进行一次精确分组,例如:
记录“01 | 2011/01/03 19:18:00.300”需要统计的时间是19:18:00.300到19:28:00.299。通过此过程,它将对记录 01,02,03 进行分组。
记录“04 | 2011/01/03 19:29:54.289”需要统计的时间是19:29:54.289到19:39:54.288。通过此过程,它将仅对记录 04 进行分组。
记录“05 | 2011/01/04 14:43:43.067”,他需要统计的时间是14:43:43.067到14:43:53.066。通过此过程,它将对记录 05、06、07 进行分组。
记录“08 | 2011/01/04 14:57:55.608;” 需要统计记录的时间是14:57:55.608到15:07:55.607。通过此过程,它将对记录 08、09、10、11、12、13、14、15 进行分组。
输入数据:
ID TS
01 2011/01/03 19:18:00.300
02 2011/01/03 19:18:00.503
03 2011/01/03 19:20:26.335
04 2011/01/03 19:29:54.289
05 2011/01/04 14:43:43.067
06 2011/01/04 14:50:10.727
07 2011/01/04 14:52:26.827
08 2011/01/04 14:57:55.608
09 2011/01/04 14:57:55.718
10 2011/01/04 14:59:13.603
11 2011/01/04 15:00:34.260
12 2011/01/04 15:02:55.687
13 2011/01/04 15:04:51.917
14 2011/01/04 15:06:24.760
15 2011/01/04 15:07:15.378
Run Code Online (Sandbox Code Playgroud)
输出数据:
ID TS Count …Run Code Online (Sandbox Code Playgroud) 我有以下查询:
query =
"SELECT
data #>> '{id}' AS id,
data #>> '{name}' AS name,
data #>> '{curator}' AS curator,
data #> '{$isValid}' AS \"$isValid\",
data #> '{customer}' AS customer,
data #> '{$createdTS}' AS \"$createdTS\",
data #> '{$updatedTS}' AS \"$updatedTS\",
data #> '{$isComplete}' AS \"$isComplete\",
(count(keys))::numeric as \"numProducts\",
created_at
FROM
appointment_intakes,
LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN
appointment_intake_users
ON
appointment_intake_users.appointment_intake_id = appointment_intakes.id
#{where_clause}
GROUP BY id"
Run Code Online (Sandbox Code Playgroud)
并导致以下错误:
对表“ appointment_intakes”的FROM子句条目的无效引用
添加后,该错误开始发生:
LATERAL jsonb_object_keys(data #> '{products}') keys
Run Code Online (Sandbox Code Playgroud)
和
(count(keys))::numeric as \"numProducts\"
Run Code Online (Sandbox Code Playgroud)
因为我需要计算产品数量。 …
我有一个新表,看起来像这样,有3e6行:
CREATE TABLE everything_crowberry (
id SERIAL PRIMARY KEY,
group_id INTEGER,
group_type group_type_name,
epub_id TEXT,
reg_user_id INTEGER,
device_id TEXT,
campaign_id INTEGER,
category_name TEXT,
instance_name TEXT,
protobuf TEXT,
UNIQUE (group_id, group_type, reg_user_id, category_name, instance_name)
);
Run Code Online (Sandbox Code Playgroud)
对于我的上下文,这通常是有意义的,并且大多数查询的速度都可以接受。
但是这样的查询不是很快:
analytics_staging=> explain analyze select count(distinct group_id) from everything_crowberry;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=392177.29..392177.30 rows=1 width=4) (actual time=8909.698..8909.699 rows=1 loops=1)
-> Seq Scan on everything_crowberry (cost=0.00..384180.83 rows=3198583 width=4) (actual time=0.461..6347.272 rows=3198583 loops=1)
Planning time: 0.063 ms
Execution time: 8909.730 ms
(4 rows)
Time: 8910.110 …Run Code Online (Sandbox Code Playgroud) sql postgresql distinct postgresql-performance postgresql-9.5
我有一个名为资产的表。这是 ddl:
create table assets (
id bigint primary key,
name varchar(255) not null,
value double precision not null,
business_time timestamp with time zone,
insert_time timestamp with time zone default now() not null
);
create index idx_assets_name on assets (name);
Run Code Online (Sandbox Code Playgroud)
我需要为每个资产名称提取最新的(基于 insert_time)值。这是我最初使用的查询:
SELECT DISTINCT
ON (a.name) *
FROM home.assets a
WHERE a.name IN (
'USD_RLS',
'EUR_RLS',
'SEKKEH_RLS',
'NIM_SEKKEH_RLS',
'ROB_SEKKEH_RLS',
'BAHAR_RLS',
'GOLD_18_RLS',
'GOLD_OUNCE_USD',
'SILVER_OUNCE_USD',
'PLATINUM_OUNCE_USD',
'GOLD_MESGHAL_RLS',
'GOLD_24_RLS',
'STOCK_IR',
'AED_RLS',
'GBP_RLS',
'CAD_RLS',
'CHF_RLS',
'TRY_RLS',
'AUD_RLS',
'JPY_RLS',
'CNY_RLS',
'RUB_RLS',
'BTC_USD'
)
ORDER BY …Run Code Online (Sandbox Code Playgroud) sql postgresql greatest-n-per-group distinct-on postgresql-performance
postgresql ×10
sql ×8
indexing ×3
distinct ×2
performance ×2
algorithm ×1
distinct-on ×1
group-by ×1
jsonb ×1
lateral ×1
merge ×1
minute ×1
self-join ×1
sql-update ×1
time ×1
trigram ×1