2013-05-28 31 views
0

我有3个表交易者,city_state,city_present。Oracle SQL查询性能

我在交易员表中有400万行,我的查询至少需要20秒。 city_present和cities表中几乎没有记录。

以下是我的查询。

 
    

select t.trader_id, t.name, t.city, t.state from ( SELECT distinct c.city, c.state FROM city_present p,city_state c WHERE p.name = 'TEST_TEST' AND c.city = p.city AND c.state = p.state ) cs, trader t where AND t.city = cs.city AND t.state = cs.state AND t.name = 'john test' AND t.is_valid= 1

我对客户(市,州,名称,valid_customer)指数 子查询所需的时间比第二个是20秒左右服用..它是外部查询较少。

有人可以帮助我如何减少查询时间。

+1

对于初学者来说,显示解释计划将有所帮助。 – OldProgrammer

+0

您的查询返回了多少行? –

回答

0

我假设你有一个trader.name的索引,可能还包括trader.is_valid?

而且是真正需要的区别吗?这是否真的需要成为一个内联视图,还是可以成为一个常规联接?

+0

约返回35行。 – user12121

+0

我是否需要在交易者名称,is_valid,城市,州列或只是名称和is_valid列索引? – user12121

+0

您几乎可以肯定需要将trader.name作为最小索引。无论您是否需要is_valid上的一个,都取决于它能够节省多少时间,以便能够从索引中找到is_valid = 1,而无需转到表格。每个is_valid值有多少行?您可能不需要索引中的所有交易者列 - 请先尝试。 –

0

有一些事情你可以尝试不添加任何东西到您的模式:在你的子查询,你永远不会选择city_present什么,所以你可以把它变成IN/EXISTS

select t.trader_id, t.name, t.city, t.state from 
(
SELECT c.city, c.state 
FROM city_state c 
WHERE EXISTS (
    select null 
    from city_present p 
    where 
    p.name = 'TEST_TEST' 
    AND c.city = p.city 
    AND c.state = p.state) 
) 
cs, trader t 
where 
AND t.city = cs.city 
AND t.state = cs.state 
AND t.name = 'john test' 
AND t.is_valid= 1 

然后,同样的道理也适用到CS。所以,你可以改写为:

select t.trader_id, t.name, t.city, t.state from 
trader t 
where 
exists (
    SELECT null 
    FROM city_state c 
    WHERE EXISTS (
     select null 
     from city_present p 
     where 
     p.name = 'TEST_TEST' 
     AND c.city = p.city 
     AND c.state = p.state) 
    AND t.city = c.city 
    AND t.state = c.state 
) 
AND t.name = 'john test' 
AND t.is_valid= 1 

您也可以尝试压扁的子查询:

select t.trader_id, t.name, t.city, t.state from 
trader t 
where 
exists (
    SELECT null 
    FROM city_present p,city_state c 
    WHERE p.name = 'TEST_TEST' 
    AND c.city = p.city 
    AND c.state = p.state 
    AND t.city = c.city 
    AND t.state = c.state 
) 
AND t.name = 'john test' 
AND t.is_valid= 1 

从这里,你应该调查关于索引:

  • trader.name和/或交易.id
  • (city_state.city,city_state.state)and(city_present.city,city_present.state)
+0

谢谢,添加索引后性能有所提高。 – user12121