大家好日子,
我最近不得不搬到UcanAccess'来自Access JET Engine的引擎,我不太熟悉"标准" SQL查询,不使用" INNER JOIN"功能。我根据以前的一个问题编写了以下SQL查询,这个问题来自关于DELETE子句的问题,但是这个查询:
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格式)运行完全正常,整个查询仅返回100-200结果。
任何帮助将不胜感激。 感谢
答案 0 :(得分:3)
您的查询执行笛卡尔积(CROSS JOIN)在分组之前,因此它可能会 ELABORATE 出现大量事件,因为您不要在TreatmentRecords和SInformation之间指定任何连接条件。
例如,如果你有10000条S信息记录和1000条治疗记录,提到2015年3月,SID <70000,将为GROUP BY详细记录10百万条记录。 显然这没有意义。
即使Jet引擎可以解释您对最终分组的意图,并通过不执行整个笛卡尔产品来实施替代策略和执行计划,但您的查询很可能 DBMS(即Hsqldb)。
重写这个错误的查询,会增加价值。
答案 1 :(得分:2)
除了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条件,如果该列上有索引,则可以避免表扫描。