【问题标题】:How to use min() and max() in an efficient way?如何有效地使用 min() 和 max()?
【发布时间】:2012-05-07 05:19:26
【问题描述】:

我有一个 sql 查询,我检查一个值是否在表的最大值和最小值之间。我现在实现如下:

SELECT spectrum_id, feature_table_id
FROM 'spectrum', 'feature' 
WHERE `spectrum`.msrun_msrun_id = 1
AND `feature`.msrun_msrun_id = 1
AND (SELECT min(rt) FROM `convexhull` WHERE `convexhull`.feature_feature_table_id =  `feature`.feature_table_id) <= scan_start_time 
AND scan_start_time <= (SELECT max(rt) FROM `convexhull` WHERE 'convexhull'.feature_feature_table_id = 'feature'.feature_table_id)
AND (SELECT min(mz) FROM `convexhull` WHERE `convexhull`.feature_feature_table_id = `feature`.feature_table_id) <= base_peak_mz 
AND base_peak_mz <= (SELECT max(mz) FROM `convexhull` WHERE `convexhull`.feature_feature_table_id = `feature`feature_table_id)

这运行非常缓慢,因为每次运行此查询时我都会从凸包中选择 4 次,所以我尝试使用内部连接对其进行改进:

SELECT spectrum_id, feature_table_id 
FROM 'spectrum', 'feature'
INNER JOIN `convexhull` ON `convexhull`.feature_feature_table_id = `feature`.feature_table_id
WHERE `spectrum`.msrun_msrun_id = ? "+ 
AND `feature`.msrun_msrun_id = ? "+
AND min(`convexhull`.rt) <= scan_start_time "+
AND scan_start_time <= max(`convexhull`.rt) "+
AND min(`convexhull`.mz) <= base_peak_mz "+
AND base_peak_mz <= max(`convexhull`.mz)", spectrumFeature_InputValues)

但是,min() 和 max() 语句只能在 select 语句之后使用。如何让第一次查询更有效率,这样我就可以得到最小和最大 rt 和 mz 而不必进行 4 次查询?

【问题讨论】:

    标签: sql performance sqlite max min


    【解决方案1】:

    编辑:又过了几分钟,又看了一遍,发现所有数据都来自那个表,所以这样的东西应该可以工作

    SELECT 
        spectrum_id
        ,feature_table_id
    FROM 
        spectrum AS s
        INNER JOIN feature AS f
            on f.msrun_msrun_id = s.msrun_msrun_id
        INNER JOIN (select 
             feature_feature_table_id
             ,min(rt) AS rtMin
            ,max(rt) AS rtMax
            ,min(mz) AS mzMin
            ,max(mz) as mzMax
         FROM 
            convexhull
         GROUP BY 
             feature_feature_table_id
         ) AS t
         ON t.feature_feature_table_id = f.feature_table_id
    WHERE
        s.msrun_msrun_id = 1
        AND s.scan_start_time >= t.rtMin
        AND s.scan_start_time <= t.rtMax
        AND base_peak_mz >= t.mxMin
        AND base_peak_mz <= t.mzMax
    

    我认为您想从凸包表中进行选择并按 feature_feature_table_id 进行分组,以获得该分组中的最小和最大 rt。

    然后,您可以将该选择括在括号中,为其命名(如 t)并加入它。

    希望这足以让您上路.. 如果不在这里创建示例架构:http://sqlfiddle.com/

    并输入您的查询,我可以修改它。

    作为旁注,我认为您希望在特定字段上加入这些表,而不是使用 where 子句比较从两者中进行选择:

    SELECT spectrum_id, feature_table_id
    FROM 'spectrum', 'feature' 
    WHERE `spectrum`.msrun_msrun_id = 1
    AND `feature`.msrun_msrun_id = 1
    

    和:

    SELECT 
        spectrum_id
        ,feature_table_id
    FROM 
        spectrum AS s
        INNER JOIN feature AS f
            on f.msrun_msrun_id = s.msrun_msrun_id
    WHERE
        s.msrun_msrun_id = 1
    

    如果我有什么问题,请告诉我。

    【讨论】:

    • 我刚刚完成了您编写的顶部部分的测试,它使查询快了大约 3 倍,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    • 2012-08-26
    • 2018-08-30
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多