我有一个存储过程,可以创建并使用临时#table
如果临时#table
将在其上创建索引,则会对某些查询进行极大优化。
但是,在存储过程中创建索引失败:
create procedure test1 as
SELECT f1, f2, f3
INTO #table1
FROM main_table
WHERE 1 = 2
-- insert rows into #table1
create index my_idx on #table1 (f1)
SELECT f1, f2, f3 FROM #table1 (index my_idx) WHERE f1 = 11 -- "QUERY X"
当我调用上述内容时,“QUERY X”的查询计划显示表扫描。
如果我只是在存储过程外部运行上面的代码,则消息会显示以下警告:
在表'#table1'的FROM子句中指定为优化程序提示的索引'my_idx'不存在。优化器会选择另一个索引。
在运行ad-hoc(存储过程之外)时,可以通过在索引创建后添加“go”两次分割上面的代码来解决这个问题:
create index my_idx on #table1 (f1)
go
现在,“QUERY X”查询计划显示索引“my_idx”的使用。
问题:当存储过程中存在“单独的批处理”时,如何模仿“创建索引”?我不能像上面的ad-hoc副本那样插入“go”。请注意,我知道“将'QUERY X'拆分为单独的存储过程”的解决方案“,我正在寻找一种可以避免这种情况的解决方案。
P.S。如果重要,则在Sybase 12(ASE 12.5.4)
上更新:
在提出问题之前,我在谷歌搜索期间看到了几个“架构碰撞”的引用。但在我的情况下似乎没有发生这种情况。
您可以创建表格,填充表格,在其上创建索引并选择值 从它在相同的porc和优化器完全花费它的基础上 准确的资讯。这被称为“架构碰撞”并且已经到位 从11.5.1开始。
答案 0 :(得分:0)
Sybase文档说您在同一存储过程中创建并使用临时索引:
http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.dc20023_1251/html/optimizer/X26029.htm
我认为要解决这个问题,你需要将存储过程分成至少两部分,一部分用于创建和填充表,然后构建索引,然后再运行第二部分来运行选择查询。
答案 1 :(得分:0)
我不确定你是如何得到这个问题的,可能是在旧版本的Sybase中,但是对于版本12.5.4我尝试执行与你建议的相同的事情,但在我的情况下,优化器正确建议使用索引在存储过程中创建。通常在存储过程中,我们不需要将sql分成批处理,因为否则我们也需要为create table命令分别创建一个批处理。
如果我们尝试在同一批次(而不是存储过程)中创建索引,我们将获得上面指定的相同错误,因为我们尝试在表上创建索引然后尝试使用它在同一批次内。通常,Sybase服务器将一次性编译整个批处理,因此出现问题。但就Sybase 12.5.4中的存储过程而言,没有任何问题。