优化一个sql查询,其中包含大量连接和组合的记录

时间:2018-05-18 17:35:44

标签: sql ibm-midrange db2-400

这是我目前的代码,它的作用是:它将具有相同ID(KEYVADD)的记录分组,然后根据having语句删除它们。

现在看来这个查询需要5-10分钟才能运行,因为审计文件非常大,然后加入并选择语句。我希望减少这个时间,但是我仍然努力以一种仍会返回相同结果的方式来做到这一点。当我尝试但是在HAVING中进入WHERE语句时,它只是在状态槽中拉出带有空值的命令而不是时间而不是一起去除ID。

DECLARE @paramdate DATETIME , @paramdatechar varchar(30),@warehouse int
set @warehouse = 711
set @paramdate= '2018-05-17 12:00:00.000'
set @paramdatechar = CONVERT(varchar(30),@paramdate,121)



exec('  select KEYVADD
    ,min(case when VALUADD=0 then timestmp else null end) as "Status0"
    ,min(case when VALUADD=2 then timestmp else null end) as "Status2"
    ,min(case when VALUADD=4 then timestmp else null end) as "Status4"
    ,min(case when VALUADD=5 then timestmp else null end) as "Status5"
    ,min(case when VALUADD=7 then timestmp else null end) as "Status7"
    ,min(case when VALUADD=8 then timestmp else null end) as "Status8"
    ,min(case when VALUADD=9 then timestmp else null end) as "Status9"
    ,min(nmdoh) as "Customer"
    ,min(c.scscn) as "Container"
    ,min(whsoh) as "Warehouse"
    ,min(preoh) as "Preorder"
    from Audit a
left outer join orderhp h on left(a.KEYVADD,7) = h.ONHOH
left outer join ordercnhpc on h.onhoh = c.onhcn
WHERE 
    whsoh = '''+@warehouse+'''
    and IMGTADD = ''A''
GROUP BY KEYVADD
HAVING(
     (min(case when VALUADD=2 then timestmp else null end) <= '''+ @paramdatechar +''')
        and (
                (
                min(preoh) = ''Y''
                and(  
                    (min(case when VALUADD=4 then timestmp else null end) IS NOT NULL)
                    or   (min(case when VALUADD=5 then timestmp else null end) IS NOT NULL)
                    or   (min(case when VALUADD=7 then timestmp else null end) IS NOT NULL)
                    or   (min(case when VALUADD=8 then timestmp else null end) IS NOT NULL)
                    or   (min(case when VALUADD=9 then timestmp else null end) IS NOT NULL)
                    )
                )
                or
                (
                min(preoh) = ''N''
                )
            )
        and(
                (
                    min(case when VALUADD=7 then timestmp else null end) IS NULL
                    and  min(case when VALUADD=8 then timestmp else null end) IS NULL
                    and  min(case when VALUADD=9 then timestmp else null end) IS NULL
                )
                or
                (
                    min(case when VALUADD=7 then timestmp else null end) >= '''+ @paramdatechar +'''
                    or   min(case when VALUADD=8 then timestmp else null end) >= '''+ @paramdatechar +'''
                    or   min(case when VALUADD=9 then timestmp else null end) >= '''+ @paramdatechar +'''
                )
            )
        ) ') at IBMAS400

结果:

    793841800 2018-05-16 14:46:24.5720000   2018-05-16 13:20:25.2250000 2018-05-16 14:46:36.8530000 NULL    NULL    2018-05-17 13:57:03.0230000 NULL    name 1                  711 N
    793843700 2018-05-16 14:46:24.6410000   2018-05-16 13:20:27.2830000 2018-05-16 14:46:36.8750000 NULL    NULL    2018-05-17 13:57:03.5800000 NULL    name 2                      711 N
    793847800 2018-05-16 14:46:24.7080000   2018-05-16 14:21:21.8600000 2018-05-16 14:46:36.9820000 NULL    NULL    2018-05-17 13:57:04.0010000 NULL    name 3                  711 N
    793849100 2018-05-16 14:46:24.7400000   2018-05-16 14:21:23.5210000 2018-05-16 14:46:37.0430000 NULL    NULL    2018-05-17 13:57:04.3380000 NULL    name 4                      711 N
    793855500 2018-05-16 15:49:01.7590000   2018-05-16 15:21:18.1300000 2018-05-16 15:49:15.5260000 NULL    NULL    2018-05-17 13:57:05.0660000 NULL    name 5                  711 N
    793856100 2018-05-16 15:49:01.7810000   2018-05-16 15:21:19.2200000 2018-05-16 15:49:15.5520000 NULL    NULL    2018-05-17 13:57:05.5630000 NULL    name 6                  711 N
    793865100 2018-05-16 19:54:46.2840000   2018-05-16 16:19:53.7890000 2018-05-16 19:54:57.1080000 NULL    NULL    2018-05-17 13:57:05.9330000 NULL    name 7                      711 N
    793871500 2018-05-16 19:54:46.3350000   2018-05-16 17:20:24.8500000 2018-05-16 19:54:57.1820000 NULL    NULL    2018-05-17 14:07:04.8690000 NULL    name 8                  711 N

我希望有一种方法可以通过改变选择的工作方式或其他方式来减少时间,并且非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

https://www.red-gate.com/simple-talk/sql/learn-sql-server/sql-server-index-basics/

你可以尝试一下,看看它是否更快?另外,如果你在select中注释掉字段c.scscn,为什么你甚至需要加入ordercnhp表呢?

- ,min(c.scscn)为“容器”

DECLARE @paramdate DATETIME , @paramdatechar varchar(30),@warehouse int
set @warehouse = 711
set @paramdate= '2018-05-17 12:00:00.000'
set @paramdatechar = CONVERT(varchar(30),@paramdate,121)



exec('  select KEYVADD
    ,min(case when VALUADD=0 then timestmp else null end) as "Status0"
    ,min(case when VALUADD=2 then timestmp else null end) as "Status2"
    ,min(case when VALUADD=4 then timestmp else null end) as "Status4"
    ,min(case when VALUADD=5 then timestmp else null end) as "Status5"
    ,min(case when VALUADD=7 then timestmp else null end) as "Status7"
    ,min(case when VALUADD=8 then timestmp else null end) as "Status8"
    ,min(case when VALUADD=9 then timestmp else null end) as "Status9"
    ,min(nmdoh) as "Customer"
    --,min(c.scscn) as "Container"
    ,min(whsoh) as "Warehouse"
    ,min(preoh) as "Preorder"
    from Audit a
left outer join orderhp h on left(a.KEYVADD,7) = h.ONHOH
-- Is the ordercnhp needed?
--left outer join ordercnhp c on h.onhoh = c.onhcn
WHERE 
    whsoh = '''+@warehouse+'''
    and IMGTADD = ''A''
GROUP BY KEYVADD
HAVING(
     (min(case when VALUADD=2 then timestmp else null end) <= '''+ @paramdatechar +''')
        and (
                (
                    min(preoh) = ''N''
                )
                or
                (
                    min(preoh) = ''Y''
                    and(  
                            (min(case when VALUADD in (4,5,7,8,9) then timestmp else null end) IS NOT NULL)
                        )
                )
            )
        and(
                (
                    min(case when VALUADD in (7,8,9) then timestmp else null end) IS NULL
                )
                or
                (
                    min(case when VALUADD in (7,8,9) then timestmp else null end) >= '''+ @paramdatechar +'''
                )
            )
        ) ') at IBMAS400