我的应用程序中有一种情况,用于显示符合不同标准的数据计数。由于计数的性能随着数据库的增长而降低,我们决定使用exists子句仅显示可用性信息。
以下是我的表结构
Table: DocInfo
---------------------------------------
DocId number
DocName varchar(250)
DocStatus number
SignedBy number
ForwardedBy number
ForwardCount number
DocOwner number
MgrID number
ProjectId number
进行计数的当前查询就像这样
SELECT NVL(SUM(CASE
WHEN (DocStatus IN (1150,1155,1170,1182,1190) AND
DocOwner=56366 AND
ForwardCount=0)
THEN 1
ELSE 0
END), 0) "ForReview",
NVL(SUM(CASE
WHEN (DocStatus IN (1200) And
MgrID = 56366 AND
ForwardCount = 0 )
THEN 1
ELSE 0
END), 0) "Accepted" ,
NVL(SUM(CASE
WHEN (DocStatus IN (1150,1155,1170,1182,1190) AND
DocOwner=56366 AND
MgrID = 0 )
THEN 1
ELSE 0
END), 0) "Waiting"
FROM DocInfo
WHERE ProjectId = 313 and
(DocOwner = 56366 or MgrID = 56366)
我需要将计数更改为exists
子句,以便我可以显示每个类别中的文档是否可用。
由于此更改是为了提高性能,因此不建议将其作为不同的查询运行。请帮助我,我的知识有限。
很抱歉错过了我已尝试过的部分。
我已将上述查询更改为带有exists子句的联合,如下所示。
SELECT 'ForReview' AS A
FROM DUAL
WHERE EXISTS (SELECT NULL
FROM DocInfo
WHERE ProjectId = 313 and
(DocOwner = 56366 or MgrID = 56366) and
(DocStatus IN (1150,1155,1170,1182,1190) AND
DocOwner=56366 AND
ForwardCount=0))
UNION
SELECT 'Accepted' AS A
FROM DUAL
WHERE EXISTS (SELECT NULL
FROM DocInfo
WHERE ProjectId = 313 and
(DocOwner = 56366 or MgrID = 56366) and
(DocStatus IN (1200) And
MgrID = 56366 AND
ForwardCount = 0 ))
UNION
SELECT 'Waiting' AS A
FROM DUAL
WHERE EXISTS (SELECT NULL
FROM DocInfo
WHERE ProjectId = 313 and
(DocOwner = 56366 or MgrID = 56366) and
(DocStatus IN (1150,1155,1170,1182,1190) AND
DocOwner=56366 AND
MgrID = 0))
我只提到了3个条件,而我的实际应用程序有8个不同的条件要添加到此查询中。因此,当我有8个Exists子句时,它在内部运行为8个不同的查询,实际上它需要更多时间 - 整个联合查询中的单个段只需要560毫秒,而所有查询一起花费大约7秒来生成输出。
由于我的要求仅是识别任何此类记录的可用性,因此我不想浏览整个记录集并对其进行计数。
无论如何都要优化/重写此查询
谢谢
答案 0 :(得分:3)
"所以当我有8个Exists子句时,它在内部运行为8个不同 查询,实际上它需要更多的时间 - 单个段 整个联合查询只需560毫秒,而所有查询一起 大约需要7秒钟来生成输出。"
惊喜,惊喜。运行相同的查询八次的速度并不比运行该查询一次快。
现在确实EXISTS可以更快,因为它只需要找到符合给定条件的单行,而不是检索整个数据集。但是,您刚刚将检索到的数据转移到WHERE子句中,因此数据库仍然需要执行相同的工作量。事实上,它显然做了很多工作,因为7s > (560ms * 8)
。
要正确解决问题,您需要了解数据库的工作原理以及如何调整它。 Find out more。
首先,定义一个调整目标。您的原始查询需要半秒才能运行:这不是快速闪电,但速度非常快。为什么这是个问题?你想以多快的速度运行它?
接下来,运行EXPLAIN PLAN。查询是否使用索引?它的索引使用效率如何>选择了多少百分比的行?
现在您还需要低估数据。所选数据是均匀分布在整个表中还是存在集群?有些项目,业主或经理比其他项目有更多的记录吗?这种分布如何影响绩效?
请记住,调整是一门科学,而且很复杂:有关于这个主题的全书,有些人作为性能故障排除者做了非常好的生活。它需要大量有关系统的信息,包括应用程序的功能以及数据库正在执行的活动的低级信息。我们可以帮助您找到更高效的解决方案,但我们不能只看一个简单的查询,并告诉您如何重写,以便更快地运行。