使用IN子句优化Oracle查询

ins*_*ect 2 java sql oracle query-optimization

我在参数中使用两个查询,并在其中填充了PreparedStatementusing setLongsetStringoperation。

查询1

SELECT A, B FROM TABLE1 WHERE A in  (SELECT A FROM TABLE2 WHERE C in (?,?,?) )
Run Code Online (Sandbox Code Playgroud)

查询2

SELECT A, B FROM TABLE1 WHERE A in (?,?)
Run Code Online (Sandbox Code Playgroud)

有人告诉我它为每个可能的设置大小创建一个唯一的查询,并污染了Oracle的SQL缓存。另外,由于大小不固定,oracle可以为每个查询选择不同的执行计划。

可以应用哪些优化来使其更好?

如果我创建大小为50的子句列表并使用伪/冗余变量填充其余的列表,那会好吗?

如果我没看错,那么除非将其提取出来并再次用作语句列表,否则很难优化条款中的选择语句。

das*_*ght 5

有人告诉我它为每个可能的设置大小创建一个唯一的查询,并污染了Oracle的SQL缓存。

假设IN列表中的项目数可以在请求之间更改,这是正确的。如果IN列表内的问号数量保持不变,则缓存不会有“污染”。

另外,由于大小不固定,oracle可以为每个查询选择不同的执行计划。

那也是正确的。不过,这是一件好事。

可以应用哪些优化来使其更好?如果我创建大小为50的子句列表并使用伪/冗余变量填充其余的列表,那会好吗?

绝对。我多次使用此技巧:不是生成精确大小的列表,而是生成长度可被一定数整除的列表(我使用16,但也可以使用50)。如果实际列表的大小不能被16整除,那么我将最后一项添加的次数与达到正确长度所需的次数相同。

这样实现的唯一优化是减少查询计划缓存中的项目。

  • @instanceOfObject从那时起到现在,数据库引擎可以(并且将)通过使用哈希表在极短的时间内消除重复项。即使使用五十个值,这也浪费很少的时间。另一方面,如果缺少预先建立的查询计划,DB引擎将再次运行优化器,这比50次哈希查找要慢得多,即使对于最简单的SQL查询也是如此。那时和现在之间的唯一区别是缓存未命中发生的频率。使用更大的查询计划缓存,您会减少未命中的次数,因此从长远来看,这种优化的重要性将降低。 (2认同)