Performance 我的Oracle查询在非常短和非常长的执行时间之间变化。什么会导致这一点?
[如果我重复发布此消息,我表示歉意-我以为我上周五发布了一个问题,但我的帐户没有显示任何问题。] 主要问题是:Linux上的Oracle11g在4秒到1.000秒的时间内完成并返回一个特定查询的数据。Oracle在两个不同的执行计划之间来回切换,其中一个执行计划的速度非常缓慢 我们已经确定了对查询的几个语义相同的更改,这使得Oracle不断选择快速执行计划。我们担心由于无明显原因的来回切换而出现错误或数据损坏 任何关于这种行为原因的想法都将不胜感激 以下是具体细节: 我们对一个模式的四个简单表进行了非常简单的Oracle查询。当我们运行这个查询时,执行时间会有很大的不同——如果我们按顺序运行它20次,三到四次执行需要4秒才能返回数据,其他执行需要超过1000秒 我们已经尝试记录执行计划,Oracle在两个不同的执行计划之间进行切换-一个计划给出4秒的响应,另一个给出1.000秒以上的响应 每个表大约有30000行,响应大约为5000行。当Oracle选择慢速执行计划时,获取每个结果行的时间会以指数级的速度变慢—响应的前1000行需要2秒,第1.000-2.000行需要30秒,第2.000-3.000行需要90秒,依此类推 我们在使用的列上有索引,对于快速执行计划,它们按预期使用。慢速计划总是对其中一个索引进行“快速完全扫描”(成本约为2.000),而快速计划则对同一索引进行“范围扫描”(成本约为2)。计划完全不同——可能是因为这个。我们尝试过删除这个索引并重新创建它,但结果没有什么不同 此外,查询在其中一个表的主键列上包含NOT LIKE。如果我们将这些不相似的表达式移到引用列上,Oracle总是选择快速执行计划 我们不想锁定执行计划,因为查询会发生微妙的变化。此外,这种在执行计划之间来回的改变让我们感到担忧——它散发出bug或数据损坏的气味 有人知道为什么甲骨文会这样做吗?除了锁定执行计划之外,还有其他解决方法吗 以下是在快速和慢速执行计划之间切换的查询:Performance 我的Oracle查询在非常短和非常长的执行时间之间变化。什么会导致这一点?,performance,oracle,Performance,Oracle,[如果我重复发布此消息,我表示歉意-我以为我上周五发布了一个问题,但我的帐户没有显示任何问题。] 主要问题是:Linux上的Oracle11g在4秒到1.000秒的时间内完成并返回一个特定查询的数据。Oracle在两个不同的执行计划之间来回切换,其中一个执行计划的速度非常缓慢 我们已经确定了对查询的几个语义相同的更改,这使得Oracle不断选择快速执行计划。我们担心由于无明显原因的来回切换而出现错误或数据损坏 任何关于这种行为原因的想法都将不胜感激 以下是具体细节: 我们对一个模式的四个简单表进
select g.ucid, a.ucid
from account a, groups g, group_members gm, group_groups_flat ggf
where a.ucid = gm.ucid_member
and gm.ucid_group = ggf.ucid_member
and ggf.ucid_group = g.ucid
and a.status = 'active'
and g.unix_gid is not null
and gm.valid_from <= sysdate
and gm.valid_to >= sysdate
and g.ucid not like '$_%' escape '$'
and g.ucid not like 's$_%' escape '$'
你提供的信息有些不一致。在这个问题中,您说一个计划使用
快速全扫描
,而另一个计划对同一索引使用范围扫描
;但是在dbas站点上的问题版本中,您显示了实际的执行计划,并且两者都使用快速全扫描
作为唯一基于索引的操作。这两个计划之间的真正区别似乎在于连接顺序,因为要连接的第一个表之间缺少连接条件,所以第二个顺序需要执行一些更大的内存中操作
无论如何,对于如何进一步调查这一点,我有一些建议。一个想法是激活,它记录所有优化器活动,并查看是否可以比较获得两个不同计划的运行结果。输出不是很漂亮,可能很难理解,但它可能会让您了解正在发生的事情
我的另一个想法是,您在查询中使用的唯一非文字值是
SYSDATE
,因此我想知道时间的变化是否会导致优化器的算法发生变化,从而产生不同的计划。我不确定优化器如何处理SYSDATE。您可以尝试使用绑定变量替换对SYSDATE的调用,并在执行查询之前在其他代码中设置日期值。如果您使用的是11g,则可以使用计划管理来阻止Oracle切换计划
您以前确实问过这个问题,但在-您的问题是。您的帐户似乎没有链接。对于这类问题,这可能是一个更合适的论坛。对不一致之处表示歉意。我连续五天都在思考这个问题——范围扫描实际上是在同一个Oracle实例中以相同的模式(但数据较少)生成的计划。关于SYSDATE的想法非常有趣。我曾尝试用TO_DATE()文本替换SYSDATE,但不幸的是,它没有影响结果。仍然在高效和可怕之间来回变换。
select g.ucid, a.ucid
from account a, groups g, group_members gm, group_groups_flat ggf
where a.ucid = gm.ucid_member
and gm.ucid_group = ggf.ucid_member
and ggf.ucid_group = g.ucid
and a.status = 'active'
and g.unix_gid is not null
and gm.valid_from <= sysdate
and gm.valid_to >= sysdate
and ggf.ucid_group not like '$_%' escape '$'
and ggf.ucid_group not like 's$_%' escape '$'
CREATE TABLE "PDB"."GROUPS"
(
"UCID" VARCHAR2(256 BYTE),
"UNIX_GID" NUMBER(*,0),
[...]
PRIMARY KEY ("UCID") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS STORAGE(INITIAL 3145728 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "PDB" ENABLE,
CONSTRAINT "GN_FK" FOREIGN KEY ("UCID") REFERENCES "PDB"."NAMESPACE" ("UCID") ENABLE
)
CREATE TABLE "PDB"."ACCOUNT"
(
"UCID" VARCHAR2(256 BYTE),
"STATUS" VARCHAR2(10 BYTE) NOT NULL ENABLE,
[...]
PRIMARY KEY ("UCID") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS STORAGE(INITIAL 2097152 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "PDB" ENABLE,
FOREIGN KEY ("STATUS") REFERENCES "PDB"."ACCOUNT_STATUS" ("STATUS") ENABLE,
CONSTRAINT "AN_FK" FOREIGN KEY ("UCID") REFERENCES "PDB"."NAMESPACE" ("UCID") ENABLE,
)
CREATE TABLE "PDB"."GROUP_MEMBERS"
(
"UCID_GROUP" VARCHAR2(256 BYTE) NOT NULL ENABLE,
"UCID_MEMBER" VARCHAR2(256 BYTE) NOT NULL ENABLE,
"VALID_FROM" DATE NOT NULL ENABLE,
"VALID_TO" DATE NOT NULL ENABLE,
CONSTRAINT "GROUP_MEMBERS_GROUPS_FK1" FOREIGN KEY ("UCID_GROUP") REFERENCES "PDB"."GROUPS" ("UCID") ENABLE,
CONSTRAINT "GROUP_MEMBERS_MEMBER_FK1" FOREIGN KEY ("UCID_MEMBER") REFERENCES "PDB"."ACCOUNT" ("UCID") ENABLE
)
CREATE INDEX "PDB"."IDX_GROUP_MEMBERS_FROM" ON "PDB"."GROUP_MEMBERS"("VALID_FROM")
CREATE INDEX "PDB"."IDX_GROUP_MEMBERS_TO" ON "PDB"."GROUP_MEMBERS"("VALID_TO")
CREATE TABLE "PDB"."GROUP_GROUPS_FLAT"
(
"UCID_GROUP" VARCHAR2(256 BYTE),
"UCID_MEMBER" VARCHAR2(256 BYTE),
CONSTRAINT "GROUP_GROUPS_FLAT_GROUPS_FK1" FOREIGN KEY ("UCID_GROUP") REFERENCES "PDB"."GROUPS" ("UCID") ENABLE,
CONSTRAINT "GROUP_GROUPS_FLAT_GROUPS_FK2" FOREIGN KEY ("UCID_MEMBER") REFERENCES "PDB"."GROUPS" ("UCID") ENABLE
)
CREATE INDEX "PDB"."IDX_GROUP_GROUPS_FLAT_GROUP" ON "PDB"."GROUP_GROUPS_FLAT("UCID_GROUP")
CREATE INDEX "PDB"."IDX_GROUP_GROUPS_FLAT_MEMBER" ON "PDB"."GROUP_GROUPS_FLAT("UCID_MEMBER")