Ist*_*tel 14 sql t-sql indexing temp-tables
我需要做一个非常复杂的查询.有一次,这个查询必须连接到一个不幸被编入索引的视图.此视图也是连接大表的复杂视图.
View的输出可以简化为:
PID (int), Kind (int), Date (date), D1,D2..DN
Run Code Online (Sandbox Code Playgroud)
其中PID和日期和种类字段不是唯一的(可能有多个行具有相同的pid,种类,日期组合),但是那些将用于连接的行如此
left join ComplexView mkcs on mkcs.PID=q4.PersonID and mkcs.Date=q4.date and mkcs.Kind=1
left join ComplexView mkcl on mkcl.PID=q4.PersonID and mkcl.Date=q4.date and mkcl.Kind=2
left join ComplexView mkco on mkco.PID=q4.PersonID and mkco.Date=q4.date and mkco.Kind=3
Run Code Online (Sandbox Code Playgroud)
现在,如果我这样做,查询的执行需要很长时间,因为复杂的视图运行了三次我假设,并且在其大量行中只有一些实际使用(例如,40000只有2000只是用过的)
我所做的是声明@temptable,并从ComplexView中插入@temptable select*,其中Date ... - 每次查询一次我只选择我将从我的ComplexView中使用的行,然后我加入这个@temptable.
这显着缩短了执行时间.
但是,我注意到,如果我在我的数据库中创建一个表,并在PID,Kind,Date(非唯一聚簇)上添加聚簇索引并从该表中获取数据,那么从该表执行delete*并插入到此复杂视图中的表需要几秒钟(3或4),然后在我的查询中使用此表(左连接三次)将查询时间从1分钟缩短到30秒!
所以,我的问题是,首先 - 是否可以在声明的@temptables上创建索引.然后 - 我看到人们谈论"创建#temptable"语法.也许这就是我需要的?我在哪里可以读到声明@temptable和create #temptable之间的区别?我应该如何使用我的查询?(此查询适用于MS Reporting Services报告,如果重要的话).
#tablename是一个物理表,存储在tempdb服务器将在创建它的连接关闭时自动删除,@tablename是一个存储在内存中的表,并且在创建它的批处理/过程的生命周期中存在,就像本地变量一样.
您只能向#temp表中添加(非PK)索引.
create table #blah (fld int)
create nonclustered index idx on #blah (fld)
Run Code Online (Sandbox Code Playgroud)
这不是一个完整的答案,但 #table 将创建一个您需要删除的临时表,否则它将保留在您的数据库中。@table 是一个表变量,其持续时间不会超过您的脚本。
另外,我认为这篇文章将回答您问题的另一部分。