我有一个查询,在运行时运行得非常好(快速),但是当我尝试按连接值搜索时,性能就会下降。
为保持高性能,我有哪些选择?我知道明显的解决方案是不按连接的字符串搜索,但是在某些情况下我不得不这样做。我该如何处理这些情况。
示例1:快速运行
parquet-tools
示例2:运行缓慢
Select * From
(
With Exmp1 AS
(
Select ID, RCD From Table1 a where EFFDT = (Select Max(b.EFFDT)
FROM Table1 b
Where a.ID = b.ID and a.RCD = b.RCD) and status = 'A'
)
Select USERNAME, RCD
From MainTable MT Inner Join Exmp1 E1 ON MT.ID = E1.ID
)
Where USERNAME = 'test1'
如果您想知道为什么将整个查询都包装在一个选择中,则使用此查询的应用程序希望查询以“选择”开头。我已经尝试过不使用“ with”子句重写它,但是得到的结果相同。
Select * From
(
With Exmp1 AS
(
Select ID, RCD From Table1 a where EFFDT = (Select Max(b.EFFDT)
FROM Table1 b
Where a.ID = b.ID and a.RCD = b.RCD) and status = 'A'
)
Select USERNAME || '@domain.com', RCD
From MainTable MT Inner Join Exmp1 E1 ON MT.ID = E1.ID
)
Where USERNAME = 'test1@domain.com'
============= 编辑以获取其他信息:
表1具有四列:ID,RCD,EFDFT,STATUS。重要的是,我只能获取最新记录(EFFDT)和状态值为“ A”的记录。
主表有两列:ID,USERNAME。我无法更改此表或创建其他表,数据库视图。我必须使用今天存在的这些数据,并且只能以SQL查询的形式进行交互。
对于给定的USERNAME@domain.com,理想的结果是USERNAME@domain.com和RCD。
请注意,这只是一个具体示例,我们对此主题的一般帮助非常感谢。
答案 0 :(得分:2)
连接字符串时,将阻止SQL优化器使用MainTable (USERNAME)
上的现有索引。这迫使引擎沿着不同的[慢速]路线行驶;可能是HEAP [TABLE]扫描。就这么简单。
如果您确实需要提供完整的电子邮件地址,那么我将在最后一步而不是之前计算连接,实际上是回到您的第一个选项。例如:
Select USERNAME || '@domain.com', RCD From
(
With Exmp1 AS
(
Select ID, RCD From Table1 a where EFFDT = (Select Max(b.EFFDT)
FROM Table1 b
Where a.ID = b.ID and a.RCD = b.RCD) and status = 'A'
)
Select USERNAME, RCD
From MainTable MT Inner Join Exmp1 E1 ON MT.ID = E1.ID
)
Where USERNAME = 'test1'
编辑:
更进一步,您可以重新定义整个查询,并找出简化查询后可以轻松看到的优化:
MT.USERNAME
列可能比a.STATUS
更具选择性,因此您应该首先对其进行过滤。ix2
。例如:
Select
MT.USERNAME || '@domain.com', a.RCD
From MainTable MT
join Table1 a on a.ID = MT.ID
where MT.USERNAME = 'test1'
and a.status = 'A'
and a.EFFDT = (
Select Max(b.EFFDT) FROM Table1 b Where a.ID = b.ID and a.RCD = b.RCD
)
现在,为了使此查询快速真实,您需要以下索引。看来您已经有了第一个:
create index ix1 on MainTable (USERNAME); -- You already have this one
create index ix2 on Table1 (ID, RCD, EFFDT);
第二编辑:如果您确实想使用完整的用户名进行搜索,则可以在表达式上添加索引。以您的“示例2”为例,如下所示更改WHERE
条件:
Select * From
(
With Exmp1 AS
(
Select ID, RCD From Table1 a where EFFDT = (Select Max(b.EFFDT)
FROM Table1 b
Where a.ID = b.ID and a.RCD = b.RCD) and status = 'A'
)
Select USERNAME || '@domain.com', RCD
From MainTable MT Inner Join Exmp1 E1 ON MT.ID = E1.ID
)
Where USERNAME || '@domain.com' = 'test1@domain.com' -- changed here
然后添加以下索引:
create index ix3 on MainTable (USERNAME || '@domain.com');
这应该使查询速度更快,因为过滤先决条件将与索引完全匹配。