Sql 具有可选参数的快速查询,无需动态查询

Sql 具有可选参数的快速查询,无需动态查询,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,之后在网上进行缓慢的查询。我注意到,将查询转换为动态查询将使其执行更快。这似乎与传递不同参数时使用错误的执行计划有关 这太慢了 SELECT ProductID, ProductName FROM TransactionHistory WHERE (ProductID = pProductId OR pProductId IS NULL) AND (ReferenceOrderID = pOrderId OR pOrderId IS NULL) AND (TransactionType = pT

之后在网上进行缓慢的查询。我注意到,将查询转换为动态查询将使其执行更快。这似乎与传递不同参数时使用错误的执行计划有关

这太慢了

SELECT ProductID, ProductName FROM TransactionHistory
WHERE (ProductID = pProductId OR pProductId IS NULL)
AND (ReferenceOrderID = pOrderId OR pOrderId IS NULL)
AND (TransactionType = pTransactionType OR pTransactionType IS NULL)
这很快(请忽略错误的查询和注入)


我目前正在研究10g,但很快将转移到11g。对于11g,有没有一种方法可以让查询在没有动态查询的情况下快速运行?

如果使用的第一个值不具有代表性,您是否在谈论绑定变量窥视创建次优计划?(). 您想要一个具有唯一查询的硬解析,这会影响SQL语句缓存吗?如果是这样的话,那么11g的自适应光标共享或许会有所帮助?@AlexPoole仍在对此进行研究。“你可能给了我一条很好的途径。”链接问题中的答案部分错误。对于这种逻辑,可以使用静态SQL语句,并使其性能良好。看到我在那个问题上的新答案了吗。太长,读不下去了使用
NVL
,优化器将添加一个
FILTER
操作,并在运行时选择不同的执行计划。
vSql := 'SELECT ProductID, ProductName FROM TransactionHistory WHERE 1=1 '

IF pProductId IS NOT NULL THEN
    vSql := vSql || ' AND ProductID = ' || pProductId
END IF;

IF pOrderId IS NOT NULL THEN
    vSql := vSql || ' AND ReferenceOrderID = ' || pOrderId
END IF;

IF pTransactionType IS NOT NULL THEN
    vSql := vSql || ' AND TransactionType = ' || pTransactionType
END IF;

OPEN pCursor FOR vSql;