如何缩短长时间运行的SQL Multiple-Join语句

时间:2017-09-01 10:23:34

标签: sql jpa derby

以下SQL语句对我造成了问题。

它会定期运行以对不断插入表中的数据进行采样。每次在每个表中插入10条记录,与执行此查询并行。

这些表是使用JPA构建的,但我将SQL作为本机查询运行,以尝试优化查询。

问题: 我试图以固定的速率对数据进行采样(理想情况下是5或10分钟)。但是当数据集变大时,查询的执行时间会超过固定的速率,而且我没有得到稳定的样本。

示例:

Sample rate 10 seconds : query 740 ms
Sample rate 20 seconds : query 7.8 seconds
Sample rate 30 secodns : query 106 seconds **<- Unsustainable**

查询中的每个表都有GWY(长),SLV(整数)和STMP(java.sql.Timestamp)上的复合主键。此外,每个字段的索引都是GWYSLVSTMP。有非外键。

底层数据库是嵌入式Derby。

测试表明,查询首先对join语句中的表数非常敏感。

SQL语句:

SELECT i1.GWY AS GWY, i1.SLV AS SLV, inv.SN AS SN, inv.NUMB AS NUMB, 
    MAX(cnt.TOT_COUNT) AS TOT_COUNT, AVG(inv.PWR_ACT) AS PWR_ACT, 
    MAX(sta.STAT) AS STAT, MIN(inv.CUR1) AS AC_CUR1_MN, MAX(inv.CUR1) AS 
    AC_CUR1_MX, AVG(inv.CUR1) AS AC_CUR1_AV, MIN(inv.CUR2) AS AC_CUR2_MN, 
    MAX(inv.CUR2) AS AC_CUR2_MX, AVG(inv.CUR2) AS AC_CUR2_AV, MIN(inv.CUR3) 
    AS AC_CUR3_MN, MAX(inv.CUR3) AS AC_CUR3_MX, AVG(inv.CUR3) AS AC_CUR3_AV, 
    MIN(inv.VOLT) AS AC_VOLT_MN, MAX(inv.VOLT) AS AC_VOLT_MX, AVG(inv.VOLT) 
    AS AC_VOLT_AV, MIN(idc.CUR1) AS DC_CUR1_MN, MAX(idc.CUR1) AS DC_CUR1_MX, 
    AVG(idc.CUR1) AS DC_CUR1_AV, MIN(idc.CUR2) AS DC_CUR2_MN, MAX(idc.CUR2)
    AS DC_CUR2_MX, AVG(idc.CUR2) AS DC_CUR2_AV, MIN(idc.CUR3) AS DC_CUR3_MN, 
    MAX(idc.CUR3) AS DC_CUR3_MX, AVG(idc.CUR3) AS DC_CUR3_AV, MIN(idc.CUR4) 
    AS DC_CUR4_MN, MAX(idc.CUR4) AS DC_CUR4_MX, AVG(idc.CUR4) AS DC_CUR4_AV, 
    MIN(idc.CUR5) AS DC_CUR5_MN, MAX(idc.CUR5) AS DC_CUR5_MX, AVG(idc.CUR5) 
    AS DC_CUR5_AV, MIN(idc.CUR6) AS DC_CUR6_MN, MAX(idc.CUR6) AS DC_CUR6_MX, 
    AVG(idc.CUR6) AS DC_CUR6_AV, MIN(idc.CUR7) AS DC_CUR7_MN, MAX(idc.CUR7) 
    AS DC_CUR7_MX, AVG(idc.CUR7) AS DC_CUR7_AV, MIN(idc.CUR8) AS DC_CUR8_MN, 
    MAX(idc.CUR8) AS DC_CUR8_MX, AVG(idc.CUR8) AS DC_CUR8_AV, MIN(idc.CUR9) 
    AS DC_CUR9_MN, MAX(idc.CUR9) AS DC_CUR9_MX, AVG(idc.CUR9) AS DC_CUR9_AV, 
    MIN(idc.CUR10) AS DC_CUR10_MN, MAX(idc.CUR10) AS DC_CUR10_MX,
    AVG(idc.CUR10) AS DC_CUR10_AV, MIN(idc.CUR11) AS DC_CUR11_MN, 
    MAX(idc.CUR11) AS DC_CUR11_MX, AVG(idc.CUR11) AS DC_CUR11_AV, 
    MIN(idc.CUR12) AS DC_CUR12_MN, MAX(idc.CUR12) AS DC_CUR12_MX, 
    AVG(idc.CUR12) AS DC_CUR12_AV, MIN(i1.VOLT) AS DC_VOLT1_MN, MAX(i1.VOLT) 
    AS DC_VOLT1_MX, AVG(i1.VOLT) AS DC_VOLT1_AV, MIN(i2.VOLT) AS 
    DC_VOLT2_MN, MAX(i2.VOLT) AS DC_VOLT2_MX, AVG(i2.VOLT) AS DC_VOLT2_AV, 
    MIN(i3.VOLT) AS DC_VOLT3_MN, MAX(i3.VOLT) AS DC_VOLT3_MX, AVG(i3.VOLT) 
    AS DC_VOLT3_AV, MIN(i1.MPPT) AS DC_MPPT1_MN, MAX(i1.MPPT) AS 
    DC_MPPT1_MX, AVG(i1.MPPT) AS DC_MPPT1_AV, MIN(i2.MPPT) AS DC_MPPT2_MN, 
    MAX(i2.MPPT) AS DC_MPPT2_MX, AVG(i2.MPPT) AS DC_MPPT2_AV, MIN(i3.MPPT) 
    AS DC_MPPT3_MN, MAX(i3.MPPT) AS DC_MPPT3_MX, AVG(i3.MPPT) AS DC_MPPT3_AV 

FROM INV1 i1 
LEFT JOIN INV2 i2 ON (i1.GWY = i2.GWY AND i1.SLV = i2.SLV)
LEFT JOIN INV3 i3 ON (i1.GWY = i3.GWY AND i1.SLV = i3.SLV)
LEFT JOIN IDC idc ON (i1.GWY = idc.GWY AND idc.SLV = i2.SLV)
LEFT JOIN INV_C inv ON (i1.GWY = inv.GWY AND i1.SLV = inv.SLV)
LEFT JOIN INV_S sta ON (i1.GWY = sta.GWY AND i1.SLV = sta.SLV)
LEFT JOIN I_COUNT cnt ON (i1.GWY = cnt.GWY AND i1.SLV = cnt.SLV) 

WHERE (i1.STMP BETWEEN ?1 AND ?2) 
    AND (i2.STMP BETWEEN ?1 AND ?2)
    AND (i3.STMP BETWEEN ?1 AND ?2) 
    AND (idc.STMP BETWEEN ?1 AND ?2) 
    AND (inv.STMP BETWEEN ?1 AND ?2) 
    AND (sta.STMP BETWEEN ?1 AND ?2) 
    AND (cnt.STMP BETWEEN ?1 AND ?2) 

GROUP BY i1.GWY, i1.SLV, inv.SN, inv.NUMB

0 个答案:

没有答案