Sybase 上的慢 SQL 查询

Slow SQL query on Sybase

我正在尝试从数据库中提取信息。 Sybase ASE 16(虽然不确定 SP)。我自己没有直接访问数据库的权限,所以我不得不请同事运行提取我随后使用的信息的代码。

首先执行以下代码:

create table AAA (
    Operacion varchar(10) null,
    Actual smallint null,
    Castigado smallint null,
    RentasVar smallint null)
go

Table 索引是使用 bcp 从文本文件填充的。实际上,Castigado 和 RentasVar 要么是 0 要么是 1。

然后这个代码:

create view XXX as
    select Operacion, cast(convert(char(8), FecAplica, 112) as int) as FecAplica,
            IdPolizaSeg, SaldoInsSeg, CapitalSeg, InteresSeg,
            IvaSeg, MontoSeg, SegVenc
        from SEG_Vencim
        where Operacion in (
            select Operacion from AAA 
                where Actual=1)
go

create view YYY as
    select Operacion, IdTipoMov, DescMov, IdMoneda, StatuMov,
            cast(convert(char(8), FecMov, 112) as int) as FecMov,
            cast(convert(char(8), FecVencMov, 112) as int) as FecVencMov,
            cast(convert(char(8), FecPago, 112) as int) as FecPago,
            MontoMov, IvaMov, TotalMov, MontoDelPago
        from Movimientos
        where (Operacion in (
            select Operacion from AAA where Castigado=1))
                or (Operacion in (
                    select Operacion from AAA where Actual=1)
                        and (FecPago=null or FecPago>dateadd(dd, -30, current_date())))
go

Movimientos 中的字段操作是 varchar(10)。我不能修改这个 table.

发出 bcp 指令将 XXX 的内容复制到文本文件中。几秒钟后任务完成,写了一个 aprox 文件。 140MB。 发出 bcp 指令将 YYY 的内容复制到文本文件中。该任务在将近 7 小时后完成,写入了一个 aprox 文件。 70 MB。

所以我的问题是第二条 bcp 指令耗时太长。 我读到 where 子句上的函数可能效率低下,所以我让我的同事使用

再试一次
and (FecPago=null or FecPago>='2020-09-30'))

而不是

and (FecPago=null or FecPago>dateadd(dd, -30, current_date())))

但没有用。

AAA 有 80,000 到 90,000 条记录。在上面放一个索引会有帮助吗? 我读到取消嵌套查询可能 help,这对我的情况有帮助吗?如果是这样,为什么第一个查询中的嵌套查询有效?

我不能 运行 自己测试,也无权访问执行计划。我意识到如果我不提供额外的信息,可能无法就此给我建议。

我没有太多使用 Sybase 的经验,但在 MSSQL(与 Sybase 共享它的祖先)中 ORs 往往是性能杀手。按照 markp-fuso 的建议将它们更改为 UNION 结构通常是个好主意。

就是说,我想知道将 OR 完全移入 sub-select 会发生什么:

create view YYY as
    select <your fields>
     from Movimientos
     where Operacion in (select Operacion 
                           from AAA 
                          where ( Castigado = 1)
                             or ( (Actual = 1 and (FecPago=null or FecPago > dateadd(dd, -30, current_date()))))
                        )

不确定优化器可能会对上述内容执行什么操作。因此,我想知道如果我们首先将 AAA 上的操作强制为 'materialize' 会发生什么......您可以尝试一下吗?

create view YYY as
    select <your fields>
     from Movimientos m
     JOIN (SELECT DISTINCT Operacion 
             from AAA 
            where ( Castigado = 1)
               or ( (Actual = 1 and (FecPago=null or FecPago > dateadd(dd, -30, current_date()))))
          ) d
      ON d.Operacion = m.Operacion 
      

祝你好运。

PS:除了使用 UNION 来摆脱 OR 之外,您还可以尝试使用 WHERE EXISTS() 而不是 IN() 构造.