【问题标题】:Slow Query Due to Multiple, JOIN-laden Subqueries由于多个 JOIN-laden 子查询导致查询缓慢
【发布时间】:2017-07-11 11:29:40
【问题描述】:

我目前正在开发 LIMS。我需要检索与需要使用某种准备方法进行准备的实验室样本相关的信息。 (我对此进行了很多简化,如有任何错误,我们深表歉意。)我需要在查询结果中生成的列是:

Sample number|
Container type|
List of ALL chain of custodies this sample appears on|
List of ALL analysis items this sample needs to be prepped for|
List of ALL prep methods this sample needs to go through

例如:

Sample 1|100g|101, 102, 103, 104|BTEX, TPH|Moisture Content, Pentane
Sample 2|200g|101, 103|BTEX, Atterberg Limits|Headspace, Moisture Content, Pentane
Sample 3|200g|101, 102, 104|Atterberg Limits|Headspace, Moisture Content

我必须从三个不同的表中检索最后三列的列表。我目前正在使用三个不同的子查询来执行此操作:

SELECT
  lab_coc_samples.Sample_Number,
  lab_coc_samples.Container,
  (Subquery 1),
  (Subquery 2),
  (Subquery 3)
FROM  lab_coc_samples
JOIN  lab_coc                            ON lab_coc_samples.CoC_ID = lab_coc.Data_ID
JOIN  lab_analysis_items_to_prep_methods ON lab_coc.Analysis_Item = lab_analysis_items_to_prep_methods.Analysis_Code
WHERE lab_analysis_items_to_prep_methods.Prep_Code = 1

子查询 1:每个样本将出现在几个不同的监管链上,所以我对第一列的子查询是:

SELECT GROUP_CONCAT( DISTINCT lab_coc_samples.CoC_ID SEPARATOR ',')
FROM lab_coc_samples

WHERE lab_coc_samples.Sample_Code = s1.Sample_Code
GROUP BY lab_coc_samples.Sample_Code

子查询 2:每个监管链都有一个分析项目,但每个样本将链接到多个分析项目,因为它出现在多个 CoC 上:

SELECT GROUP_CONCAT( DISTINCT lab_analysis_items.Name SEPARATOR ',')
FROM lab_coc_samples

JOIN lab_coc            ON lab_coc.Data_ID = lab_coc_samples.CoC_ID
JOIN lab_analysis_items ON lab_analysis_items.Code = lab_coc.Analysis_Item

WHERE lab_coc_samples.Sample_Code = s1.Sample_Code
GROUP BY lab_coc_samples.Sample_Code

子查询 3:每个分析项目都链接到多个 prep 方法(因此:多个样本与多个分析项目相关,这些分析项目与多个 prep 方法相关 --joy):

SELECT GROUP_CONCAT( DISTINCT lab_prep_methods.Name SEPARATOR ', ') 
FROM lab_coc_samples

JOIN lab_coc                            ON lab_coc_samples.CoC_ID = lab_coc.Data_ID
JOIN lab_analysis_items_to_prep_methods ON lab_analysis_items_to_prep_methods.Analysis_Code = lab_coc.Analysis_Item
JOIN lab_prep_methods                   ON lab_prep_methods.Code = lab_analysis_items_to_prep_methods.Prep_Code

WHERE lab_coc_samples.Sample_Code = s1.Sample_Code
GROUP BY lab_coc_samples.Sample_Code

这个数据库中有数千个样本需要准备,这使得这个查询非常慢。如何在不修改数据库结构的情况下提高此查询的效率?即使我需要有关每个表中样本的所有实例的信息,我能否以某种方式使用连接?加入会有帮助吗?

【问题讨论】:

    标签: mysql join subquery


    【解决方案1】:

    这应该会更好一些。您实际上是在内部查询中重复外部查询,但不再是:

    SELECT
      lab_coc_samples.Sample_Number,
      lab_coc_samples.Container,
      (Subquery 1),
      (Subquery 2),
      (Subquery 3)
    
    FROM  lab_coc_samples
    
    JOIN  lab_coc
      ON  lab_coc.Data_ID = lab_coc_samples.CoC_ID
    
    JOIN  lab_analysis_items_to_prep_methods
      ON  lab_analysis_items_to_prep_methods.Analysis_Code = lab_coc.Analysis_Item
     AND  lab_analysis_items_to_prep_methods.Prep_Code = 1
    
    WHERE lab_coc_samples.Sample_Code = s1.Sample_Code
    
    GROUP BY lab_coc_samples.Sample_Code
    

    子查询 1:

    SELECT GROUP_CONCAT( DISTINCT lab_coc_samples.CoC_ID SEPARATOR ',')
    

    子查询 2:

    SELECT GROUP_CONCAT( DISTINCT lab_analysis_items.Name SEPARATOR ',')
    FROM  lab_analysis_items
    WHERE lab_analysis_items.Code = lab_coc.Analysis_Item
    

    子查询 3:

    SELECT GROUP_CONCAT( DISTINCT lab_prep_methods.Name SEPARATOR ', ') 
    FROM  lab_prep_methods
    WHERE lab_prep_methods.Code = lab_analysis_items_to_prep_methods.Prep_Code
    

    【讨论】:

    • 这看起来不错。我正在尝试实现,但我认为它只选择过滤查询中规定的 prep 方法,而不是 sample 已链接到的每个 prep 方法。它似乎也只选择了一个分析项目 p/sample。不过,CoC 列表效果很好。
    • 我知道我搞砸了…… :) 抱歉。
    【解决方案2】:

    我自己改进了查询时间,方法是创建一个包含我的列表字段的嵌套表,并向我的查询中的 JOIN 字段添加索引。最值得注意的是,向 VARCHAR 'Sample_Code' 字段添加索引可以加快几秒钟的速度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-20
      • 1970-01-01
      • 2019-01-27
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多