Sybase存储过程 - 如何在#table上创建索引?

问题描述 投票:3回答:2

我有一个存储过程,创建和使用临时#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'不存在。优化器将选择另一个索引。

通过在索引创建后添加“go”,在两个批处理中分割上面的代码,可以在运行ad-hoc(存储过程之外)时解决此问题:

create index my_idx on #table1 (f1)
go

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

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

附:如果重要,这是在Sybase 12上(ASE 12.5.4)


更新:

在提出问题之前,我在谷歌搜索期间看到过几次提到“架构颠簸”。但在我看来似乎并没有发生这种情况。

您可以创建一个表,填充它,在其上创建索引并在同一个porc中从中选择值,并让优化器根据准确的信息完全降低成本。这被称为“架构碰撞”,并且自11.5.1起就已经存在。

tsql stored-procedures indexing sybase-ase
2个回答
0
投票

Sybase文档说您在同一存储过程中创建并使用临时索引:

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

我认为要解决这个问题,你需要将存储过程分成至少两部分,一部分用于创建和填充表,然后构建索引,然后第二部分用于运行select查询。


0
投票

我不确定你是如何得到这个问题的,可能是在旧版本的Sybase中,但是对于版本12.5.4我尝试执行与你建议的相同的事情,但在我的情况下,优化器正确地建议使用在存储过程。通常在存储过程中,我们不需要将sql分成批处理,因为否则我们也需要为create table命令分别创建一个批处理批处理。

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

© www.soinside.com 2019 - 2024. All rights reserved.