如何优化可选输入id(一个特定行或整个表)的查询

时间:2015-07-03 07:41:49

标签: sql oracle plsql

我有一个查询,用于在树中的每个节点上生成名称。 此方法现在有一个输入参数(p_optional_id_node NUMBER)。

我的查询的条件如下:

(p_optional_id_node IS NULL OR p_optional_id_node=n.id)

当我使用它时,此过程需要一分钟:

p_optional_id_node=NULL

和~2秒如果:

p_optional_id_node=123.

如果我改变了条件:

(p_optional_id_node IS NULL OR p_optional_id_node=n.id)

为:

p_optional_id_node=n.id

需要大约25ms。

如果我将p_optional_id设置为一个数字并且如果我将其设置为null,则如何优化这样的查询以使用~25ms?

我不想复制此方法中的逻辑,以便为每个案例设置一个程序。

4 个答案:

答案 0 :(得分:1)

你可以这样做:

WHERE NVL(p_optional_id_node, n.id) = n.id

答案 1 :(得分:0)

由于OR,Oracle可能不再使用索引了。您可以尝试将其拆分为两个单独的查询并将它们联合起来:

Configuration objConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
        AppSettingsSection objAppsettings = (AppSettingsSection)objConfig.GetSection("appSettings");

        if (objAppsettings != null)
        {
            objAppsettings.Settings.Add("hello", "world");
            objConfig.Save();
        }

第一部分仅在p_optional_id_node为NULL时选择记录(然后获取所有记录)。第二部分仅在p_optional_id_node不为NULL时获取记录(然后获得所有匹配)。所以你仍然得到一个或另一个,但Oracle现在可以使用索引了。

答案 2 :(得分:0)

如果要在p_potional_id_node为空的情况下返回mytable中的所有行,并且所有记录的id = p_optional_id_node,则可以尝试以下操作:

为了不在此方法中复制逻辑,您可以为主逻辑创建表值函数或视图(从mytable或其他选择*),然后在方法中使用IF语句:

  1. 在p_potional_id_node为null的情况下,则返回select from function / view而不使用where子句

  2. 在某种情况下,当p_potional_id_node不为null时,则从函数/视图返回select,其中= p_potional_id_node

答案 3 :(得分:0)

select *
from mytable
where p_optional_id_node = decode(n.id, null, null, n.id);