【问题标题】:SQL Postgres query very slow with multiple tables多个表的 SQL Postgres 查询非常慢
【发布时间】:2021-12-18 18:12:47
【问题描述】:

我正在使用 Postgres。

架构

+------------+  +-----------+  +---------------------+
| employee   |  | contact   |  | powwowpersalmapping |
+------------+  +-----------+  +---------------------+
| member_id  |  | member_id |  | id_number           |
| staff_code |  | idnumber  |  | persal_number       |
+------------+  +-----------+  +---------------------+

数据

目标

如您所见,staff_code 是空白的,所以我尝试在employee 表上设置staff_code,在powwowpersalmapping 表上设置persal_number

问题

如何构造UPDATE 查询以将persal_number 复制到staff_code

问题

我正在创建一个UPDATE 查询,但是等效的SELECT 查询非常慢,所以我认为UPDATE 查询也会很慢。

SQL

我有以下几点:

如果我使用表连接运行此 SELECT 查询。它运行得非常快。

SELECT e.* FROM employee e
INNER JOIN contact c ON c.member_id = e.member_id 
INNER JOIN powwowpersalmapping m ON m.id_number = c.idnumber
WHERE e.staff_code is null or coalesce(e.staff_code, '') = '';

然后我使用多个表(无连接)运行此 SELECT 查询。它运行得很慢。

SELECT e.* FROM employee e
, contact c, powwowpersalmapping m 
WHERE c.member_id = e.member_id 
AND m.id_number = c.idnumber
AND e.staff_code is null or coalesce(e.staff_code, '') = '';

所以我正在构建一个UPDATE 查询(尚未运行),到目前为止有以下内容,但我相信它也会很慢。

UPDATE employee e
SET e.staff_code = m.persal_number
FROM contact c, powwowpersalmapping m 
WHERE c.member_id = e.member_id 
AND m.id_number = c.idnumber
AND e.staff_code is null or coalesce(e.staff_code, '') = '';

下面的呢?

UPDATE employee e
SET e.staff_code = (
    SELECT m.persal_number FROM employee e
    INNER JOIN contact c ON c.member_id = e.member_id 
    INNER JOIN powwowpersalmapping m ON m.id_number = c.idnumber
    WHERE e.staff_code is null or coalesce(e.staff_code, '') = ''
);

【问题讨论】:

  • 前两个查询不等价。它们返回不同的列。
  • 您的第二个查询隐式地执行交叉连接和过滤器。当您的意图是仅从员工返回字段时,您能解释第二个查询(可能是第一个查询)的意义吗?
  • @CetinBasoz,感谢您的回复。我正在尝试在employee 表上设置staff_code,在powwowpersalmapping 表上设置persal_number。但是,我必须使用contact 表作为连接表。
  • @Richard,对不起,我很难理解。您能否提供具有所需输出的 ​​soe 示例数据。这些查询对我来说没有意义。
  • @CetinBasoz,我已更新我的问题以包含更多信息(示例数据)。

标签: sql postgresql join sql-update


【解决方案1】:

您可以在UPDATE 语句中的FROM 子句之后使用连接:

UPDATE employee e
SET staff_code = m.persal_number
FROM contact c INNER JOIN powwowpersalmapping m 
ON m.id_number = c.idnumber
WHERE c.member_id = e.member_id AND COALESCE(e.staff_code, '') = '';

由于SELECT 查询运行速度很快(我相信所有相关列都有索引),因此它也会运行得很快。
如果您还可以摆脱 COALESCE() 函数,它会更快。
staff_code 列是否为空?如果是,则删除AND COALESCE(e.staff_code, '') = ''

【讨论】:

  • 谢谢,成功了。
猜你喜欢
  • 2022-12-19
  • 1970-01-01
  • 2021-04-21
  • 2017-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多