诀窍让SQL查询做LIKE或=取决于绑定变量?

时间:2011-02-21 13:55:42

标签: sql-server-2005 oracle11g sql-like

现在我在存储过程中有以下查询。

select * from table A where A.indexed_char_column LIKE :param1

:param1可以包含任何类型的wildcharacters,但有时可能不包含。 '%abcdef%'通常需要全表扫描,'abcdef'应该进行索引范围扫描。所以我希望SQL引擎根据这个参数使用两个不同的执行计划。

无论如何我可以使这种行为成为可能吗?我想要Oracle 11gr2和SQL Server 2005的答案。我在想是否可以在查询中包含一个虚拟参数(如注释或其他东西),这使得SQL引擎会想到两个实际上相同的查询,不要相同。

select /* use table scan */ * from table A where A.indexed_char_column LIKE :param1

select /* use index */ * from table A where A.indexed_char_column LIKE :param1

但我不知道如何做到这一点?还有其他建议吗?我应该只使用两个存储过程吗?

3 个答案:

答案 0 :(得分:2)

如果您能够根据值是否包含通配符更改提示/注释,为什么不更改语句呢?

if (contains wildcards) then
    select * from table A where A.indexed_char_column LIKE :param1;
else
    select * from table A where A.indexed_char_column = :param1;

答案 1 :(得分:1)

对于sql server,您可以使用table hintsquery hints(查看OPTION RECOMPILE)。对于其中任何一个,您可能必须足够聪明,以便自己知道要在查询中包含哪些提示。我不确定oracle的等价物是什么。

答案 2 :(得分:1)

在SQL Server中.... 如果你已经完成了一些测试,并且你确信它有两个执行计划会让你受益,那么Joel建议选择OPTION(RECOMPILE)。

但是,如果索引是狭窄且有选择性的,那么最好使用LIKE查询的索引以及equals查询。

相反,如果索引不是很有选择性,那么equals查询应该直接进行表扫描。