Sql Explain plan显示了使用分析函数和distinct查询所需的15 EB的空间量
附件是一个注释,它在每个表的旁边列出了我的模式,以指示前面提到的每个表中的行数。如果fiddle被阻止,查询看起来是这样的:Sql Explain plan显示了使用分析函数和distinct查询所需的15 EB的空间量,sql,oracle,optimization,query-optimization,sql-execution-plan,Sql,Oracle,Optimization,Query Optimization,Sql Execution Plan,附件是一个注释,它在每个表的旁边列出了我的模式,以指示前面提到的每个表中的行数。如果fiddle被阻止,查询看起来是这样的: select distinct cat_name,cat_age, co_cat_owners_id,cat_weight,cs_is_alive,os_is_current, cos_is_current, sum(cat_age) over(partition by co_cat_owners_id) running_total from (
select distinct cat_name,cat_age, co_cat_owners_id,cat_weight,cs_is_alive,os_is_current, cos_is_current,
sum(cat_age) over(partition by co_cat_owners_id) running_total
from
(
select co.cat_owners_id co_cat_owners_id,
co.cat_id co_cat_id,
co.owner_id co_owner_id,
co.vet_id co_vet_id,
cos.is_current cos_is_current,
os.is_current os_is_current,
cs.is_alive cs_is_alive,
cat.name cat_name,
cat.age cat_age,
cat.weight cat_weight
from cat_owners co,
cat_owner_statuses cos,
cat_statuses cs,
cats cat,
owners o,
owner_statuses os
where o.owner_id = co.owner_id
and cat.cat_id = co.cat_id
and cos.last_visit >= sysdate - 4/24
)
where cs_is_alive = '1'
and (cos_is_current = '1' OR os_is_current='1')
group by cat_name,cat_age,cat_weight,cs_is_alive,os_is_current,co_cat_owners_id,cos_is_current;
在我的开发环境中,explain计划在步骤上与fiddle内部的内容非常接近,但是我有几个步骤,其中内存大小为15E(exabytes),行数为4000P(petabytes)。我的问题是,在创建索引/糟糕的SQL的过程中,我在哪里成功地生成了一个15 EB的解决方案来解决这个问题,而这个解决方案应该用更少的空间和时间来解决。我注意到,调整一些复合索引创建步骤会产生稍微不同的结果,但我仍然被EB空间要求所阻碍
注意
如果将来有人没有阅读所有评论,请结合正确的连接运行以下函数:
analyze table table_name_here compute statistics;
因为您没有使用您错过的联接语法,所以将cat_状态、cat_所有者状态和所有者状态的任何行联接到其余的任何表中。这将导致这些表中的每个表与联接的表之间发生交叉联接。两个“状态”表包含多少行 考虑连接每个表,而不是用逗号列出它们,然后使用where进行筛选。我不确定SQL如何处理逗号分隔的表(也可能是交叉联接)
因为您没有使用您错过的联接语法,所以将cat_状态、cat_所有者状态和所有者状态的任何行联接到其余的任何表中。这将导致这些表中的每个表与联接的表之间发生交叉联接。两个“状态”表包含多少行 考虑连接每个表,而不是用逗号列出它们,然后使用where进行筛选。我不确定SQL如何处理逗号分隔的表(也可能是交叉联接)
您的多个表(例如
cat_status
)没有关系,因此产品联接返回的行数不胜数。也许您需要通过Fiddle示例中名为cat_vets
的表加入
至少,您应该将外部
where
条件移动到派生表查询中;将其放在外部是低效的。您的多个表(例如cat_status
)没有关系,因此产品联接返回的行数不胜数。也许您需要通过Fiddle示例中名为cat_vets
的表加入
至少,您应该将外部
where
条件移动到派生表查询中;将它放在外部是低效的。您的查询在FROM
子句中有6个表,但您只指定了两个连接条件OWNERS
有1000万行,CAT\u OWNERS
有1.2亿行,所以我猜连接会产生1.2亿行。然后你加入到CATS
,它有100万行,所以我现在假设你有1.2亿行。但是,从这里开始,您就没有更多的联接条件了。因此,您的1.2亿行中间结果与5亿行CAT_OWNER_status
表进行笛卡尔连接,该表生成1.2亿*5亿行,即60万亿行。笛卡尔将其加入1000万行CAT_STATUSES
表,最终得到60万亿*1000万行,现在我们有6*10^23行。然后再将其笛卡尔式地连接到OWNER\u status
,它有9000万行,这给了你5.4*10^31行。如果希望得到合理数量的结果,则需要指定其他连接条件以避免笛卡尔积
不幸的是,在您的工作中遵循数据模型有点困难,因为似乎有许多潜在的相互矛盾的方式将表连接在一起<例如,代码>猫兽医将猫映射到兽医,但猫主人也映射到兽医。如果没有数据和预期结果,就很难猜测表应该如何连接。我猜你想要像这样的东西
您的查询在
FROM
子句中有6个表,但您只指定了两个联接条件OWNERS
有1000万行,CAT\u OWNERS
有1.2亿行,所以我猜连接会产生1.2亿行。然后你加入到CATS
,它有100万行,所以我现在假设你有1.2亿行。但是,从这里开始,您就没有更多的联接条件了。因此,您的1.2亿行中间结果与5亿行CAT_OWNER_status
表进行笛卡尔连接,该表生成1.2亿*5亿行,即60万亿行。笛卡尔将其加入1000万行CAT_STATUSES
表,最终得到60万亿*1000万行,现在我们有6*10^23行。然后再将其笛卡尔式地连接到OWNER\u status
,它有9000万行,这给了你5.4*10^31行。如果希望得到合理数量的结果,则需要指定其他连接条件以避免笛卡尔积
不幸的是,在您的工作中遵循数据模型有点困难,因为似乎有许多潜在的相互矛盾的方式将表连接在一起<例如,代码>猫兽医将猫映射到兽医,但猫主人也映射到兽医。如果没有数据和预期结果,就很难猜测表应该如何连接。我猜你想要像这样的东西
你会建议把外层放在哪里?问题是我需要的是最新的is_alive状态,而不是第一个符合标准的状态。您建议将外部放置在何处?问题是
from owners o,
join cat_owners co on o.owner_id = co.owner_id
join cats cat on cat.cat_id = co.cat_id
join cat_owner_statuses cos on XXXXX
join cat_statuses cs on XXXXX,
join owner_statuses os on XXXXX
where cos.last_visit >= sysdate - 4/24
select distinct cat_name,cat_age, co_cat_owners_id,cat_weight,cs_is_alive,os_is_current, cos_is_current,
sum(cat_age) over(partition by co_cat_owners_id) running_total
from
(
select co.cat_owners_id co_cat_owners_id,
co.cat_id co_cat_id,
co.owner_id co_owner_id,
co.vet_id co_vet_id,
cos.is_current cos_is_current,
os.is_current os_is_current,
cs.is_alive cs_is_alive,
cat.name cat_name,
cat.age cat_age,
cat.weight cat_weight
from cat_owners co,
cat_owner_statuses cos,
cat_statuses cs,
cats cat,
owners o,
owner_statuses os,
cat_vets cv,
owner_vets ov
where o.owner_id = co.owner_id
and cat.cat_id = co.cat_id
and cos.cat_owners_id = co.cat_owners_id
and cs.cat_vets_id = cv.cat_vets_id
and os.owner_vets_id = ov.owner_vets_id
and ov.owner_id = o.owner_id
and co.vet_id = ov.vet_id
and co.vet_id = cv.vet_id
and cos.last_visit >= sysdate - 4/24
)
where cs_is_alive = '1'
and (cos_is_current = '1' OR os_is_current='1')
group by cat_name,cat_age,cat_weight,cs_is_alive,os_is_current,co_cat_owners_id,cos_is_current;