我在两张桌子之间加入了。它真的很慢,我找不到原因。 查询在非常大的客户端上的PRODUCTION环境中需要数小时。 你能问我需要了解为什么它不能正常工作吗? 我可以添加索引,对表进行分区等等。它是Oracle 10g。 我期待几千条记录。由于以下条件: f.eif_campo1!= c.fornitura AND和f.field29 ='新' 事实上,应始终对所有1800万条记录进行验证
SELECT c.id_messaggio
,f.campo1
,c.f
FROM
flows c,
tab f
WHERE
f.field198 = c.id_messaggio
AND f.extra_id = c.extra_id
and f.field1 != c.ExampleF
and f.field29 = 'New'
and c.processtype in ('Example1')
and c.flag_ann = 'N';
以下记录的选择性表示为不同值的数量:
COUNT (DISTINCT extra_id) =>17*10^6,
COUNT (DISTINCT (extra_id || field20)) =>17*10^6,
COUNT (DISTINCT field198) =>36*10^6,
COUNT (DISTINCT (field19 || field20)) =>45*10^6,
COUNT (DISTINCT (field1)) =>18*10^6,
COUNT (DISTINCT (field20)) =>47
这是执行计划[见大图] [1] ![在此处输入图像说明] [2]
额外详情: 我放松了一个记录,看看有多少记录。 30万。
![在此处输入图像说明] [7]
- 03:57分钟并行执行/ * +并行(c 8)并行(f 24)* /
- 395.358行
SELECT count(1)
FROM
flows c,
flet f
WHERE
f.field19 = c.id_messaggio
AND f.extra_id = c.extra_id
and f.field20 = 'ExampleF'
and c.process_type in ('ExampleP')
and c.flag_ann = 'N';
答案 0 :(得分:1)
简单的答案似乎是你的解释计划。您正在访问两个表by index rowid
。虽然选择一行你不能 - 据我所知 - 变得更快,在你的情况下,你选择的不仅仅是一行。
这意味着,对于每一行,您一次只能进入两个表,当您查看表或索引的很大一部分时,这不是您想要做的。
我的建议是强制你的一个或两个表full scan
。首先尝试使用较小的驱动程序:
SELECT /*+ full(c) */ c.flh_id_messaggio
, f.eif_campo1
, c.f
FROM flows c,
JOIN flet f
ON f.field19 = c.flh_id_messaggio
AND f.extra_id = c.extra_id
AND f.field1 <> c.f
WHERE ...
但您可能需要将/*+ full(c) */
更改为/*+ full(c) full(f) */
。
您的索引似乎也是单独的列索引。为此,如果可能的话,我会有索引:
flows
id_messaggio, extra_id, f
flet
的{{1}}上如果您不使用全扫描,这才真正重要。或者,如果您拥有所有返回的内容并且选择在一个索引中。
答案 1 :(得分:1)
您的解释计划显示以下内容。
flh_tipo_processo_cod in ('VT','VOLTURA_ENI','CC')
flh_flag_ann = 'N'
f.idde_identif_dati_ext_id =
c.idde_identif_dati_ext_id
现在,如果flh_tipo_processo_cod
是选择性的,那么起点很好
column:即,如果它包含数百个不同的值,或者是否包含值
你的清单比较少见。它甚至可能是标志列的好路径
标识相对较少的列,其值为“N”。所以你需要了解
数据的发布 - 您拥有多少不同的值 - 及其数据
倾斜 - 哪些值经常出现或几乎不出现。整体而言
表现表明,分布和/或倾斜
flh_tipo_processo_cod
和flh_flag_ann
列并不好。
那你能做什么?一种方法是遵循Ben的建议,并使用完整 表扫描。如果您拥有Enterprise Edition许可证和足够的CPU容量 你可以尝试并行查询来改进。这可能仍然太慢,或者对其他用户来说可能太具破坏性。
另一种方法是使用更好的索引。综合指数
eni_flussi_hub(flh_tipo_processo_cod,flh_flag_ann,idde_identif_dati_ext_id,
flh_fornitura,flh_id_messaggio)
可以避免阅读该表格。是否
这将是一个新的索引或ENI_FLK_IDX3的替代取决于另一个
针对桌子的活动。您可能可以从索引压缩中受益。
查询投影中的所有列都在WHERE子句中引用。所以
您还可以在另一个表上使用复合索引以避免表读取。您需要了解Agsin数据的分布和偏差。但你可能应该选择排名最低的列。像etl_elab_interf_flat(etl_elab_interf_flat,eif_campo200,dde_identif_dati_ext_id,eif_campo1,eif_campo198)
这样的东西。可能这是一个新的指数。您不太可能希望用此替换ETL_EIF_FK_IDX4(特别是如果它确实是外键约束的索引)。
当然,这些只是我的猜测。调整是一门科学,正确地完成调整需要大量数据。使用the Wait Interface来调查数据库花费时间的位置。使用the 10053 event了解优化程序为何做出选择。但最重要的是,除非你真的知道后果,否则不会实现分区。