2012-12-06 133 views
-1

我有表查询很慢

table1的

epid  etid  id   EValue  reqdate 
----------- ----------- ----------- ------------ ---------- 
15   1   1   498925307069 2012-01-01 
185   1   2   A5973FC43CE3 2012-04-04 
186   1   2   44C6A4B776A2 2012-04-05 
205   1   2   7A0ED3F1DA13 2012-09-19 
206   1   2   77771D65F9C4 2012-09-19 
207   1   2   AD74A4AA41BD 2012-09-19 
208   1   2   9595ABE5A0C8 2012-09-19 
209   1   2   7611D2FB395B 2012-09-19 
210   1   2   04A510D6067A 2012-09-19 
211   1   2   24D43EC268F8 2012-09-19 

表2

PEId  Id   EPId 
----------- ----------- ----------- 
43   9   15 
44   10   15 
45   11   15 
46   12   15 
47   13   15 
48   14   15 
49   15   15 
50   16   15 
51   17   15 
52   18   15 

表3

PLId  PEId  Id   ToPayId 
----------- ----------- ----------- ----------- 
71   43   9   1 
72   43   9   2 
73   44   10   1 
74   44   10   2 
75   45   11   1 
76   45   11   2 
77   46   12   1 
78   46   12   2 
79   47   13   1 
80   47   13   2 

我想获得一个ID,其计数小于8在表3中,并且通过表2中的peid命令

我已经写查询

SELECT Top 1 ToPayId FROM 
(
    SELECT Count(pl.ToPayId) C, pl.ToPayId 
    FROM table3 pl 
    INNER JOIN table2 pe ON pl.peid = pe.peid 
    INNER JOIN table1 e ON pe.epid = e.epid 
    WHERE e.EtId=1 GROUP BY pl.ToPayId 
) As T 
INNER JOIN table2 p ON T.ToPayId= p.Id 
WHERE C < 8 ORDER BY p.PEId ASC 

该查询执行存储过程超过1000次使用而条件依赖于用户定义的表型中的条目。

但是它非常慢,因为我们在每个表中有数百万条记录。

任何人都可以提出更好的查询关于上述?

+0

有没有索引?也许你可以向我们展示DDL的表格。 – AakashM

+0

为了将来的参考,“十万”是一个单位,意味着100,000。 –

+0

是的,我在etid(table1),topayid,peid(table3) –

回答

0

也许尝试与having子句要想从选择

select table2.id as due 
     from table3 inner join table2 on table2.PEId=table3.PEId... 
     group by ... 
     having count(due) <8 
     order by ... 

摆脱 - >你在表3冗余ID列:似乎这对夫妻PEID相当无用和ID出现独特因此将其删除,并将表3的大小减少25%,从而提高分区的性能

+0

表结构按照业务逻辑是正确的,现在不能更改。 而我正在尝试你的建议查询(有),但它不包含table1。 table1需要检查etid的值。 –

+1

这是一个例子,如果我做你的工作,我不如得到你的薪水!?无论如何,有是正确的路要走; NB:redondancy是昂贵的,没有任何业务逻辑,我知道这种倡导浪费资源 – mikakun

+0

好吧,这很好,工作。谢谢 –

0

请问..因为您没有提供足够的示例数据,我不确定您的业务逻辑是什么。这样我就可以在盲目地修改代码。

SELECT ToPayId 
FROM (

    SELECT TOP 1 Count(pl.ToPayId) C, pl.ToPayId, pe.PEId 
    FROM table3 as pl 
     INNER JOIN table2 as pe ON pl.peid = pe.peid AND pl.ToPayId = pe.Id 
     INNER JOIN table1 e ON pe.epid = e.epid 
    WHERE e.EtId=1 
    GROUP BY pl.ToPayId, pe.PEId 
    HAVING Count(pl.ToPayId) < 8 
    ORDER BY pe.PEId ASC  

) AS T 
+0

无法找到原因,但查询返回什么。并且当您将PEId包含在group by中时,它将返回来自Db的第一条记录(所有行,如果不是top 1) –

+0

我试过了您的代码,它也不会返回任何内容。我认为如果你能更清楚地解释业务逻辑并提供更多的样本数据可能会更有帮助。 –