SQL 查询使用了大量资源但没有结果
SQL Query uses a lot of resources with no results
大家好,
我最近不得不从 Access JET 引擎转移到 UcanAccess 引擎,我对 "standard" SQL 查询不是很熟悉,没有使用 "INNER JOIN" 函数。我根据我以前从一个关于 DELETE 子句的问题中得到的答案之一编写了以下 SQL 查询,但是这个查询:
SELECT TreatmentRecords.DateGiven, TreatmentRecords.TimeGiven, SInformation.Surname, SInformation.FirstNames, SInformation.CampusCode, TreatmentRecords.Treatment, TreatmentRecords.[AmountGiven], TreatmentRecords.Diagnosis
FROM TreatmentRecords, SInformation
WHERE (((YEAR(TreatmentRecords.DateGiven)) =2015) AND ((MONTH(TreatmentRecords.DateGiven))=03) AND ((TreatmentRecords.SID)<= 70000))
GROUP BY TreatmentRecords.DateGiven, TreatmentRecords.TimeGiven, SInformation.Surname, SInformation.FirstNames, SInformation.CampusCode, TreatmentRecords.Treatment, TreatmentRecords.[AmountGiven], TreatmentRecords.Diagnosis
ORDER BY TreatmentRecords.DateGiven, SInformation.Surname, SInformation.FirstNames;
似乎什么也没做。我发现它可以将我的 CPU 提高到 96%,将我的 RAM 提高到 1GB 以上,但这就像一个递归循环。
我想请知道
a) 查询有什么问题
b) 在什么情况下查询会对您的处理器和内存执行上述操作
此查询(采用 JET 格式)运行得非常好,整个查询应该只有 return 100-200 个结果。
如有任何帮助,我们将不胜感激。
谢谢
您的查询执行笛卡尔积(交叉联接)在分组之前,因此它可能详细 出现的次数非常多,因为您没有在 TreatmentRecords 和 SInformation 之间指定任何连接条件。
例如,如果您有 10000 条 SInformation 记录和 1000 条涉及 2015 年 3 月且 SID<70000 的 TreatmentRecords,则将为 GROUP BY 详细说明 1000 万条记录。
显然这没有意义。
即使 Jet 引擎可能会根据最终分组解释您的意图,并通过不执行整个笛卡尔积来实施替代策略和执行计划,您的查询有些糟糕 对于大多数 DBMS(即 Hsqldb)。
重写这个错误的查询,会有附加值。
根据 jamadei 的回答,尝试使用 INNER JOIN 避免笛卡尔积的查询:
SELECT
TreatmentRecords.DateGiven, TreatmentRecords.TimeGiven,
SInformation.Surname, SInformation.FirstNames, SInformation.CampusCode,
TreatmentRecords.Treatment, TreatmentRecords.[AmountGiven], TreatmentRecords.Diagnosis
FROM TreatmentRecords INNER JOIN SInformation
ON TreatmentRecords.SID = SInformation.SID
WHERE TreatmentRecords.DateGiven >= #2015-03-01#
AND TreatmentRecords.DateGiven < #2015-04-01#
AND TreatmentRecords.SID <= 70000
GROUP BY
TreatmentRecords.DateGiven, TreatmentRecords.TimeGiven,
SInformation.Surname, SInformation.FirstNames, SInformation.CampusCode,
TreatmentRecords.Treatment, TreatmentRecords.[AmountGiven], TreatmentRecords.Diagnosis
ORDER BY
TreatmentRecords.DateGiven, SInformation.Surname, SInformation.FirstNames;
它还在 TreatmentRecords.DateGiven
上使用 sargable WHERE 条件,如果该列上有索引,可以避免 table 扫描。
大家好,
我最近不得不从 Access JET 引擎转移到 UcanAccess 引擎,我对 "standard" SQL 查询不是很熟悉,没有使用 "INNER JOIN" 函数。我根据我以前从一个关于 DELETE 子句的问题中得到的答案之一编写了以下 SQL 查询,但是这个查询:
SELECT TreatmentRecords.DateGiven, TreatmentRecords.TimeGiven, SInformation.Surname, SInformation.FirstNames, SInformation.CampusCode, TreatmentRecords.Treatment, TreatmentRecords.[AmountGiven], TreatmentRecords.Diagnosis
FROM TreatmentRecords, SInformation
WHERE (((YEAR(TreatmentRecords.DateGiven)) =2015) AND ((MONTH(TreatmentRecords.DateGiven))=03) AND ((TreatmentRecords.SID)<= 70000))
GROUP BY TreatmentRecords.DateGiven, TreatmentRecords.TimeGiven, SInformation.Surname, SInformation.FirstNames, SInformation.CampusCode, TreatmentRecords.Treatment, TreatmentRecords.[AmountGiven], TreatmentRecords.Diagnosis
ORDER BY TreatmentRecords.DateGiven, SInformation.Surname, SInformation.FirstNames;
似乎什么也没做。我发现它可以将我的 CPU 提高到 96%,将我的 RAM 提高到 1GB 以上,但这就像一个递归循环。
我想请知道
a) 查询有什么问题 b) 在什么情况下查询会对您的处理器和内存执行上述操作
此查询(采用 JET 格式)运行得非常好,整个查询应该只有 return 100-200 个结果。
如有任何帮助,我们将不胜感激。 谢谢
您的查询执行笛卡尔积(交叉联接)在分组之前,因此它可能详细 出现的次数非常多,因为您没有在 TreatmentRecords 和 SInformation 之间指定任何连接条件。
例如,如果您有 10000 条 SInformation 记录和 1000 条涉及 2015 年 3 月且 SID<70000 的 TreatmentRecords,则将为 GROUP BY 详细说明 1000 万条记录。 显然这没有意义。
即使 Jet 引擎可能会根据最终分组解释您的意图,并通过不执行整个笛卡尔积来实施替代策略和执行计划,您的查询有些糟糕 对于大多数 DBMS(即 Hsqldb)。
重写这个错误的查询,会有附加值。
根据 jamadei 的回答,尝试使用 INNER JOIN 避免笛卡尔积的查询:
SELECT
TreatmentRecords.DateGiven, TreatmentRecords.TimeGiven,
SInformation.Surname, SInformation.FirstNames, SInformation.CampusCode,
TreatmentRecords.Treatment, TreatmentRecords.[AmountGiven], TreatmentRecords.Diagnosis
FROM TreatmentRecords INNER JOIN SInformation
ON TreatmentRecords.SID = SInformation.SID
WHERE TreatmentRecords.DateGiven >= #2015-03-01#
AND TreatmentRecords.DateGiven < #2015-04-01#
AND TreatmentRecords.SID <= 70000
GROUP BY
TreatmentRecords.DateGiven, TreatmentRecords.TimeGiven,
SInformation.Surname, SInformation.FirstNames, SInformation.CampusCode,
TreatmentRecords.Treatment, TreatmentRecords.[AmountGiven], TreatmentRecords.Diagnosis
ORDER BY
TreatmentRecords.DateGiven, SInformation.Surname, SInformation.FirstNames;
它还在 TreatmentRecords.DateGiven
上使用 sargable WHERE 条件,如果该列上有索引,可以避免 table 扫描。