我有一个名为user_profiles
的表,现在有2400万行。我需要检索所有数据并将它们索引到Elasticsearch中。
我编写了一个程序来使用和转换数据,以便它们可索引到ES中。我在xorm中使用.Rows()
从数据库中选择数据,以便不会消耗内存。它曾经工作得很好。
我试图再次为所有文档重新编制索引,但是我发现从DB加载数据的速度要慢得多。过去,当我按顺序运行全选查询时,它几乎立即返回第一行,但现在不返回。
我检查了说明语句,发现如果我选择LIMIT为13.05M的文档,它将使用与查询顺序匹配的索引,但不会超过13.06M。
我上次索引文档时记得大约是10M
使用LIMIT 13050000
- Plan:
Node Type: "Limit"
Parallel Aware: false
Startup Cost: 0.56
Total Cost: 30928006.04
Plan Rows: 13050000
Plan Width: 592
Plans:
- Node Type: "Index Scan"
Parent Relationship: "Outer"
Parallel Aware: false
Scan Direction: "Forward"
Index Name: "user_profiles_pkey"
Relation Name: "user_profiles"
Alias: "user_profiles"
Startup Cost: 0.56
Total Cost: 56959518.12
Plan Rows: 24033936
Plan Width: 592
使用LIMIT 13060000
:
- Plan:
Node Type: "Limit"
Parallel Aware: false
Startup Cost: 30605613.02
Total Cost: 30638284.91
Plan Rows: 13060000
Plan Width: 592
Plans:
- Node Type: "Sort"
Parent Relationship: "Outer"
Parallel Aware: false
Startup Cost: 30605613.02
Total Cost: 30665697.86
Plan Rows: 24033936
Plan Width: 592
Sort Key:
- "user_id"
- "system_name"
Plans:
- Node Type: "Seq Scan"
Parent Relationship: "Outer"
Parallel Aware: false
Relation Name: "user_profiles"
Alias: "user_profiles"
Startup Cost: 0.00
Total Cost: 2357864.36
Plan Rows: 24033936
Plan Width: 592
我看到AWS RDS监视工具中有巨大的读写IOPS。我认为DB试图重新创建排序,而忽略了可以直接使用主索引的事实。我该怎么办?
这是EXPLAIN查询:
EXPLAIN ( FORMAT YAML )
SELECT *
FROM "user_profiles"
ORDER BY "user_id", "system_name"
LIMIT 13050000;
这是表结构
CREATE TABLE user_profiles
(
user_id UUID NOT NULL,
system_name VARCHAR(50) NOT NULL,
key_values TEXT NOT NULL
CONSTRAINT user_profiles_pk PRIMARY KEY (user_id, system_name)
);
答案 0 :(得分:0)
索引扫描是随机读取,通常比顺序读取更昂贵。但这几乎不取决于您的存储设备。例如,对于HDD来说,速度要慢10倍左右。 Postgres规划人员使用预期的page read costs来选择更好的选择。通过增加限制,可以使seqscan更有效。
请考虑进行多个查询,而不是一次获取1300万条记录。