9

我有一个这样的模型

在此处输入图像描述

具有以下表格大小:

+------------------+-------------+
| Table            |    Records  |
+------------------+-------------+
| JOB              |         8k  |
| DOCUMENT         |       150k  |
| TRANSLATION_UNIT |      14,5m  |
| TRANSLATION      |      18,3m  |
+------------------+-------------+

现在以下查询

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

大约需要90 秒才能完成。当我删除ORDER BYLIMIT子句时,需要19.5 secondsANALYZE已在执行查询之前对所有表运行。

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

+------------------+-------------+
| Table            |     Records |
+------------------+-------------+
| JOB              |          1  |
| DOCUMENT         |       1200  |
| TRANSLATION_UNIT |    210,000  |
| TRANSLATION      |    210,000  |
+------------------+-------------+

查询计划:

在此处输入图像描述

没有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

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

UPDATE:不带ORDER BY的同一查询的查询计划(但仍带有LIMIT子句)。

4

3 回答 3

2

这对评论来说有点太长了。order by删除该子句时,您是在比较苹果和橙子。没有order by,查询的处理部分只需要拿出 50 行。

使用 时order by,需要在对它们进行排序并选择前几行之前生成所有行。如果删除order by andlimit子句,查询需要多长时间?

作为主键的事实translation.id并没有什么不同,因为处理需要通过几个连接(过滤结果)。

编辑:

我想知道这将如何与 CTE 一起工作以首先创建表,然后再创建一个表来排序和获取结果:

with CTE as (
     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
    )
select *
from CTE
order by translation.id asc
limit 50 offset 0;
于 2013-11-04T15:35:57.530 回答
1

你在翻译(fk_id_translation_unit,id)上有一个复合索引吗?在我看来,这将有助于避免通过表访问 translation.id 的需要。

于 2013-11-04T15:04:21.730 回答
1

如果有人有同样的问题。它发生在我身上,我通过将索引更改为有序索引来解决它。索引按列 ID(PK 列)和顺序方向扩展。

像那样:

create index index_name on SCHEMA.TABLE (id asc, (sent_time IS NULL), some_id_ref, type);
于 2021-03-15T12:42:35.933 回答