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 共享它的祖先)中 OR
s 往往是性能杀手。按照 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()
构造.
我正在尝试从数据库中提取信息。 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 共享它的祖先)中 OR
s 往往是性能杀手。按照 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()
构造.