首页 > 解决方案 > 为什么 MySQL Workbench 中的“获取”(如持续时间/获取)需要很长时间才能获取非常有限的数据量?

问题描述

我正在尝试加快我们系统中的一些 sql 查询。

有问题的查询之一有一个非常慢的“IN”子句。我读到我可以在查询中构建一个临时表(使用 UNION ALL)并在该表上进行连接,以改善由“IN”子句中的隐式“OR”引起的问题。(见下文)

旧查询在我们的系统上运行大约需要 12 秒(11.8 秒持续时间 / 0.015 秒获取)。新查询的持续时间约为 0.15 秒,但是,新查询的获取时间超过 11 秒!)两个查询都返回相同的数据。大约 236 条记录,每条记录有 30 个字段。

谁能告诉我这里发生了什么?为什么读取几千字节的数据需要几秒钟的时间?

旧查询:

SELECT 
  * 
FROM 
  patients 
  LEFT JOIN patients_billing ON patients.`seq` = patients_billing.`patient_seq` 
WHERE 
  patients.`location` = "XYZ Company" 
  AND patients.`status` = "READY" 
  AND patients.`created` >= "2021-02-15" 
  AND patients.`sub_location` IN(
    'location 1', 
    'location 2', 'location 3', 
    'location 4', 
    'location 5', 
    'location 6', 
    'location 7', 
    'location 8', 
    'location 9', 
    'location 10', 
    'location 11', 
    'location 12', 
    'location 13', 
    'location 14', 
    'location 15', 
    'location 16', 
    ''
  );

新查询:


SELECT 
  * 
FROM 
  patients 
  LEFT JOIN patients_billing ON patients.`seq` = patients_billing.`patient_seq` 
  INNER JOIN (
    SELECT 'location 1' as sub_location
    UNION ALL
    SELECT 'location 2' as sub_location
    UNION ALL
    SELECT 'location 3' as sub_location
    UNION ALL
    SELECT 'location 4' as sub_location
    UNION ALL'
    SELECT 'location 5' as sub_location
    UNION ALL
    SELECT 'location 6' as sub_location
    UNION ALL
    SELECT 'location 7' as sub_location
    UNION ALL
    SELECT 'location 8' as sub_location
    UNION ALL
    SELECT 'location 9' as sub_location
    UNION ALL
    SELECT 'location 10' as sub_location
    UNION ALL
    SELECT 'location 11' as sub_location
    UNION ALL
    SELECT 'location 12' as sub_location
    UNION ALL
    SELECT 'location 13' as sub_location
    UNION ALL
    SELECT 'location 14' as sub_location
    UNION ALL
    SELECT 'location 15' as sub_location
    UNION ALL
    SELECT 'location 16' as sub_location
    UNION ALL
    SELECT '' as sub_location  
  ) as mf_table
    ON mf_table.sub_location = patients.sub_location 
WHERE 
  patients.`location` = "XYZ Company" 
  AND patients.`status` = "READY" 
  AND patients.`created` >= "2021-02-15";

请随时提出任何问题以进行澄清。

谢谢!

标签: mysqlquery-optimizationmysql-workbench

解决方案


持续时间是 Workbench 检索结果集第一行所用的时间。

Fetch 是检索其余行所需的时间。

看起来这两个查询需要大约相同的时间才能完成。您的 UNION ALL 查询公式会快速提供第一行,然后将其余行逐出。您的 IN () 公式让 MySQL 服务器收集所有行,然后立即将它们发送给您。

在这两种情况下,MySQL 可能会反复扫描整个patients表以逐一查找匹配项。

我怀疑使用这些索引可以使这两种配方更快。

CREATE INDEX patient_billing_x ON patients (status, location, created, seq);
CREATE INDEX billing_patient_x ON patients_billing (patient_seq);

顺便说一句,您的问题中的查询有些令人费解。您的 WHERE 子句都patients.location在两个冲突的地方提到......

WHERE patients.location = 'XYZ Company'
  AND patients.location IN ('this', 'that', 'anything', 'but not XYZ Company')

您不应该使用该 WHERE 子句返回任何行。


推荐阅读