0

我的应用程序允许用户收集测量数据作为实验的一部分,并且需要能够报告曾经进行的所有测量。

下面是我拥有的表格的一个非常简化的版本:

CREATE TABLE EXPERIMENTS(
  EXPT_ID INT,
  EXPT_NAME VARCHAR2(255 CHAR)
);

CREATE TABLE USERS(
  USER_ID INT,
  EXPT_ID INT
);

CREATE TABLE SAMPLES(
  SAMPLE_ID INT,
  USER_ID INT
);

CREATE TABLE MEASUREMENTS(
  MEASUREMENT_ID INT,
  SAMPLE_ID INT,
  MEASUREMENT_PARAMETER_1 NUMBER,
  MEASUREMENT_PARAMETER_2 NUMBER
);

在我的数据库中有 2000 个实验,每个实验有 18 个用户。每个用户有 6 个样本要测量,每个样本将进行 100 次测量。

这意味着数据库中当前存储了 2000 * 18 * 6 * 100 = 21600000 个测量值。

我正在尝试编写一个查询,该查询将为每个用户获取测量参数 1 和 2 的 AVG() - 这将返回大约 36,000 行。

我的查询非常慢 - 我已经让它运行了 30 多分钟,但它什么也没回来。我的问题是:有没有获得平均值的有效方法?实际上是否有可能在合理的时间内(比如 2 分钟)获得这么多数据的结果?还是我不切实际?

这是(又是一个简化版本)我的查询:

SELECT 
    E.EXPT_ID,
    U.USER_ID,
    AVG(MEASUREMENT_PARAMETER_1) AS AVG_1,
    AVG(MEASUREMENT_PARAMETER_2) AS AVG_2
FROM 
    EXPERIMENTS E, 
    USERS U, 
    SAMPLES S,
    MEASUREMENTS M
WHERE
 U.EXPT_ID = E.EXPT_ID
 AND S.USER_ID = U.USER_ID
 AND M.SAMPLE_ID = S.SAMPLE_ID
GROUP BY E.EXPT_ID, U.USER_ID

这将为每个 expt_id/user_id 组合返回一行以及 2 个测量参数的平均值。

4

1 回答 1

1

对于您的查询,无论如何,DBMS 都需要读取完整的测量表。到目前为止,这是要读取的数据的最大部分,如果查询优化得好(稍后会谈到),则需要花费最多时间的部分。这意味着查询的最短运行时间大约是从存储的任何位置读取完整的测量表所需的时间。您可以通过检查有多少数据(以 MB 或 GB 为单位)并检查从硬盘(或存储表的位置)读取这些数据量需要多长时间来粗略估计。如果您的查询运行速度慢了 5 倍或更多,您可以确定还有优化空间。

有大量关于如何优化 oracle 查询的信息(教程、可能非常宝贵的个别提示和一般实践列表)。您不会很快了解所有这些信息。但是,如果您提供查询的执行计划(oracle 的查询优化器认为这是完成您的查询的最佳方式),我们将能够发现可以优化的步骤并提出解决方案。

于 2013-07-25T15:08:40.893 回答