PostgreSQL:非常慢的ORDER BY,主键作为排序键

two*_*wer 7 sql postgresql postgresql-performance

我有这样的模特

在此输入图像描述

具有以下表格大小:

+------------------+-------------+
| Table            |    Records  |
+------------------+-------------+
| JOB              |         8k  |
| DOCUMENT         |       150k  |
| TRANSLATION_UNIT |      14,5m  |
| TRANSLATION      |      18,3m  |
+------------------+-------------+
Run Code Online (Sandbox Code Playgroud)

现在进行以下查询

select translation.id
from "TRANSLATION" translation
   inner join "TRANSLATION_UNIT" unit
     on translation.fk_id_translation_unit = unit.id
   inner join "DOCUMENT" document
     on unit.fk_id_document = document.id     
where document.fk_id_job = 11698
order by translation.id asc
limit 50 offset 0
Run Code Online (Sandbox Code Playgroud)

完成大约需要90秒.当我删除ORDER BYLIMIT子句时,需要19.5秒.在执行查询之前,已在所有表上运行ANALYZE.

对于此特定查询,这些是满足条件的记录数:

+------------------+-------------+
| Table            |     Records |
+------------------+-------------+
| JOB              |          1  |
| DOCUMENT         |       1200  |
| TRANSLATION_UNIT |    210,000  |
| TRANSLATION      |    210,000  |
+------------------+-------------+
Run Code Online (Sandbox Code Playgroud)

查询计划:

在此输入图像描述

对于没有修改的查询计划ORDER BYLIMIT在这里.

数据库参数:

PostgreSQL 9.2

shared_buffers = 2048MB
effective_cache_size = 4096MB
work_mem = 32MB

Total memory: 32GB
CPU: Intel Xeon X3470 @ 2.93 GHz, 8MB cache
Run Code Online (Sandbox Code Playgroud)

谁能看到这个查询有什么问题?

更新:没有ORDER BY的同一查询的查询计划(但仍然使用LIMIT子句).

Dav*_*dge 1

您是否在翻译上设置了复合索引(fk_id_translation_unit,id)?在我看来,这将有助于避免通过表访问 Translation.id 的需要。