2011-03-03 37 views
3

我有创建和使用临时#tableSybase存储过程 - 如何在#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”的查询计划显示表扫描。

如果我只是在存储过程外运行上面的代码,该消息将显示以下警告:

指数“my_idx”在指定为优化器提示的FROM表“#表1”的条款不存在。优化器会选择另一个索引。

这可以通过addding“走出去”创建了索引之后分两批分裂上面的代码运行的ad-hoc(存储过程外)时得到解决:

create index my_idx on #table1 (f1) 
go 

现在,“QUERY X “查询计划显示使用索引”my_idx“。

问题:在存储过程中,我该如何在单独的批处理中运行“创建索引”?我不能像在上面的特设副本那样插入“去”。请注意,我知道“将QUERY X'分解为单独的存储过程”的解决方案,并且正在寻找可以避免这种情况的解决方案。

P.S.如果它的事项,这是基于Sybase 12(ASE 12.5.4)


UPDATE

我已经看到多次提到 “模式碰撞” 我的谷歌搜索在提出这个问题之前。但这似乎并不发生在我的情况。

您可以创建一个表,填充它,在同PORC从它创建它的索引和选择值 ,并有充分的成本它基于 准确的信息优化。这被称为'模式碰撞',自11.5.1起已经到位 。

回答

0

Sybase的文档中说,创建并在同一个存储过程中使用临时指数:

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.dc20023_1251/html/optimizer/X26029.htm

我觉得要解决这个问题,你需要将你的存储过程分成至少两个部分,一个创建并填充表,然后构建索引,然后第二个运行选择查询。

+1

我在问题中明确声明'请注意,我意识到“将'QUERY X'拆分为单独的存储过程'的解决方案”,并且正在寻找一种避免这种情况的解决方案。 – DVK 2011-07-21 17:55:24

0

我不确定你是如何解决这个问题的,可能是Sybase的旧版本,但是12.5版本。4我尝试执行与你所建议的相同的事情,但在我的情况下,优化器正确地建议使用在存储过程中创建的索引。通常在存储过程中,我们不需要将sql分解为批处理,因为除此之外,我们还需要为create table命令创建一个单独的批处理。

如果我们尝试在同一批次(而不是存储过程)中创建索引,我们将获得与上面指定的相同的错误,因为我们试图在表上创建索引,然后尝试使用它在同一批次内。通常Sybase服务器会一次编译整个批次,因此会出现问题。但就Sybase 12.5.4中的存储过程而言,不存在任何问题。