-1

我有以下形式的表格:

create table orpsnumericy2(o bigint, r bigint, p bigint, s bigint);

我在 (o,r,p,s) 的所有排列上建立了 24 个索引。

我有以下表格的另一个表格

create table dictionaryfull (id, stringvalue);

有 2 个索引:(id, stringvalue)(stringvalue, id)

我使用 postgres 的 create index 命令创建了索引

然后我运行以下命令:

explain select di1.stringvalue 
from orpsnumericy2 d1, orpsnumericy2 d2, dictionaryfull di1 
where d1.R=d2.S 
and d2.P=(select id from dictionaryFull where stringvalue='"hasSuccessor"') 
and d2.O=(select id from dictionaryFull where stringvalue='"William"') 
and d1.S=di1.id;

我从命令中获得了以下计划:

 Hash Join  (cost=8820530.24..35113870.90 rows=290 width=516)
   Hash Cond: (di1.id = d1.S)
   InitPlan 1 (returns $0)
     ->  Bitmap Heap Scan on dictionaryfull  (cost=71028.27..4406162.67 rows=1358357 width=8)
           Recheck Cond: ((stringvalue)::text = '"http://yago-knowledge.org/resource/hasSuccessor"'::text)
           ->  Bitmap Index Scan on dictionaryfull_stringvalue_id_idx  (cost=0.00..70688.68 rows=1358357 width=0)
                 Index Cond: ((stringvalue)::text = '"http://yago-knowledge.org/resource/hasSuccessor"'::text)
   InitPlan 2 (returns $1)
     ->  Bitmap Heap Scan on dictionaryfull  (cost=71028.27..4406162.67 rows=1358357 width=8)
           Recheck Cond: ((stringvalue)::text = '"http://yago-knowledge.org/resource/William_J._Murphy"'::text)
           ->  Bitmap Index Scan on dictionaryfull_stringvalue_id_idx  (cost=0.00..70688.68 rows=1358357 width=0)
                 Index Cond: ((stringvalue)::text = '"http://yago-knowledge.org/resource/William_J._Murphy"'::text)
   ->  Seq Scan on dictionaryfull di1  (cost=0.00..25274570.28 rows=271671328 width=524)
   ->  Hash  (cost=8203.39..8203.39 rows=122 width=8)
         ->  Nested Loop  (cost=0.00..8203.39 rows=122 width=8)
               ->  Index Scan using opsr1 on orpsnumericy2 d2  (cost=0.00..279.67 rows=122 width=8)
                     Index Cond: ((O = $1) AND (P = $0))
               ->  Index Scan using rops1 on orpsnumericy2 d1  (cost=0.00..64.94 rows=1 width=16)
                     Index Cond: (R = d2.S)

有人可以帮我理解为什么字典完整的索引没有被使用。以及为什么查询如此缓慢的原因。

如果有人能用简单的术语向我解释查询计划,那就太好了

编辑:有人可以帮我找到最佳查询:

  select di1.stringvalue, di2.stringvalue, di3.stringvalue   
  from orpsnumericy2 d1, orpsnumericy2 d2, dictionaryfull di1,
       dictionaryfull di2,dictionaryfull di3 
  where d1.reification=d2.S and d2.P=(select id
        from dictionaryFull where stringvalue='"hasSuccessor"')   
  and d2.O=(select id from dictionaryFull  
      where  stringvalue='"William_J._Murphy"')  
 and d1.S=di1.id  
 and d1.P=di2.id  
 and d1.O=di3.id
4

1 回答 1

2
select di1.stringvalue 
from orpsnumericy2 d1, orpsnumericy2 d2, dictionaryfull di1 
where d1.R=d2.S 
and d2.P=(select id from dictionaryFull where stringvalue='"hasSuccessor"') 
and d2.O=(select id from dictionaryFull where stringvalue='"William"') 
and d1.S=di1.id;

您在这里有三个表:

orpsnumericy2 d1 , orpsnumericy2 d2,dictionaryfull di1

您未能正确地将它们连接在一起。

您需要一个条件,d2.??? = di1.??? 这就是查询“慢”的原因。基本上正在发生的事情是你有一个缺失Join,因此你正在接近cartesian product你的查询。最后你可能想要这个条件:

and d2.S=di1.id;

此外,您可能需要考虑重写类似于此NOT TESTED IN THE LEAST的查询:

   select di1.stringvalue
   from dictionaryfull di1
   join orpsnumericy2 d1 on d1.S = di1.id  
   join orpsnumericy2 d2 on d2.id = d1.id
    and d2.P=(select id from dictionaryFull where stringvalue='"hasSuccessor"') 
    and d2.O=(select id from dictionaryFull where stringvalue='"William"') 

您现在的查询非常不同:

select di1.stringvalue, di2.stringvalue, di3.stringvalue   
  from orpsnumericy2 d1, orpsnumericy2 d2, dictionaryfull di1,
       dictionaryfull di2,dictionaryfull di3 
  where d1.reification=d2.S and d2.P=(select id
        from dictionaryFull where stringvalue='"hasSuccessor"')   
  and d2.O=(select id from dictionaryFull  
      where  stringvalue='"William_J._Murphy"')  
 and d1.S=di1.id  
 and d1.P=di2.id  
 and d1.O=di3.id

你现在有五张桌子:

orpsnumericy2 d1.orpsnumericy2 d2, dictionaryfull di1,  
dictionaryfull di2,dictionaryfull di3

同样,您所做的只是增加了更多复杂性并且未能进行正确的连接。我最初的解决方案仍然认为您缺少连接。因此,添加更多表无助于解决问题。此外,您还没有为我们提供一个 sqlfiddle 来实际查看您的架构。在这个问题上,这完全是对我们部分的疯狂猜测。

您需要以下联接:

d1.x = d2.x
d1.x = d3.x
d2.x = d3.x
d1.x = di1.x
d1.x = di2.x
d1.x = di3.x
d2.x = di1.x
d2.x = di2.x
d2.x = di3.x
d3.x = di1.x
d3.x = di2.x
d3.x = di3.x
di1.x = di2.x
di1.x = di3.x
di2.x = di3.x
于 2013-11-11T20:41:41.813 回答