Sybase 存储过程 - 如何在 #table 上创建索引?
我有一个存储过程,它创建并使用临时 #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”将上面的代码分成两批来解决:
create index my_idx on #table1 (f1)
go
现在,“QUERY X”查询计划显示索引“my_idx”的使用。
问题:当“创建索引”位于存储过程内时,如何在单独的批处理中模拟运行“创建索引”?我无法像上面的临时副本那样在那里插入“go”。请注意,我知道“将‘QUERY X’拆分为单独的存储过程”的解决方案,并且正在寻找一种可以避免这种情况的解决方案。
PS 如果重要的话,这是在 Sybase 12 (ASE 12.5.4) 上
更新:
在提出问题之前,我在谷歌搜索期间看到了一些关于“架构碰撞”的参考。但在我的例子中似乎没有发生这种情况。
您可以创建一个表,填充它,在其上创建索引并选择值 从同一个 porc 中获取它,并让优化器完全基于它的成本 准确的信息。这称为“模式碰撞”并且已经到位 自 11.5.1 起。
I have a stored procedure which creates and works with a temporary #table
Some of the queries would be tremendously optimized if that temporary #table
would have an index created on it.
However, creating an index within the stored procedure fails:
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"
When I call the above, the query plan for "QUERY X" shows a table scan.
If I simply run the code above outside the stored procedure, the messages show the following warning:
Index 'my_idx' specified as optimizer hint in the FROM clause of table '#table1' does not exist. Optimizer will choose another index instead.
This can be resolved when running ad-hoc (outside the stored procedure) by splitting the code above in two batches by addding "go" after index creation:
create index my_idx on #table1 (f1)
go
Now, "QUERY X" query plan shows the use of index "my_idx".
QUESTION: How do I mimique running the "create index" in a separate batch when it's inside the stored procedure? I can't insert a "go" there like I do with the ad-hoc copy above. Please note that I'm aware of the solution of "split up the 'QUERY X' into a separate stored procedure" and am looking for a solution that will avoid that.
P.S. If it matters, this is on Sybase 12 (ASE 12.5.4)
UPDATE:
I have been seeing several references to "schema bumping" during my Googling before posing the question. But that doesn't seem to happen in my case.
You can create a table, populate it, create an index on it and select values
from it in the same porc and have the optimizer fully cost it based on
accurate information. This is called 'schema bumping' and has been in place
since 11.5.1.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Sybase 文档表示您可以在同一存储过程中创建和使用临时索引:
http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.dc20023_1251/html/optimizer/X26029.htm
我认为为了解决这个问题,您需要将存储过程分成至少两部分,第一部分用于创建和填充表,然后构建索引,第二部分用于运行选择查询。
The Sybase documentation says that you create and use a temporary index in the same stored procedure:
http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.dc20023_1251/html/optimizer/X26029.htm
I think to get around this you will need to split your stored procedure into at least two parts, one to create and populate the table then build the index, and then a second one to run the select query.
我不确定你是如何遇到这个问题的,可能是在旧版本的 Sybase 中,但是在版本 12.5.4 中,我尝试执行与你建议的相同的操作,但在我的情况下,优化器正确建议使用在存储过程。通常在存储过程中,我们不需要将 sql 分成批,因为否则我们也需要为创建表命令创建一个单独的批。
如果我们尝试在同一批处理中(而不是在存储过程中)创建索引,我们将得到与上面指定的相同的错误,因为我们尝试在表上创建索引,然后尝试在同一批处理中使用它批。通常Sybase服务器会一次性编译整个批次,因此会出现问题。但就存储过程而言,在Sybase 12.5.4中就不会有问题。
I am not sure how you are getting this problem, might be in older version of Sybase, however with version 12.5.4 I tried executing the same thing as suggested by you but in my case the optimizer correctly suggested the use of index created in the stored procedure. Usually in a stored procedure we do not need to break sql into batches because else we would have been required to have a seperate batch for create table command as well.
In case we try to create index within a same batch (not in a stored procedure) we will do get the same error as specified by you above because we are trying to create an index on a table and then trying to use it within the same batch. Usually the Sybase server will compile the whole batch in one go and hence the problem. But as far as stored procedure is concerned in Sybase 12.5.4 there will be no problem.