Home All Groups Group Topic Archive Search About
Author
19 May 2006 6:45 PM
Anatoli Dontsov
Hi, All!

I have many tables with name convention tYYYYMMDD
and set of SPs to perform some calculations.

Ideally I would need "temporary view' functionality.

CREATE PROC MyProc (@tablename)
AS
CREATE TABLE #mytable (dt DATETIME)
EXEC ('CREATE VIEW #myview AS SELECT * FROM ' + tablebame)
EXEC Calc1
EXEC Calc2
SELECT * FROM #mytable
DROP TABLE #mytable
DROP VIEW #myview
RETURN 0.


CREATE PROC Calc1
AS
INSERT #mytable SELECT max(col1) FROM #myview

CREATE PROC Calc2
AS
INSERT #mytable SELECT min(col1) FROM #myview


CalcX  - can be very complex and I got many of them.

Unfortunately SQL doesn't support "temporary view'.
Is there a workarround?

Bye, Anatol

Author
19 May 2006 8:41 PM
Jim Underwood
A"temporary view" would be a temporary table.  Use two temp tables to do
what you need.

However, I don't see why you need to use this view at all.  Why not just do
this...

Even better, post a full description of what you are trying to do, including
DDL and sample data, and you may be able to eliminate the dynamic SQL and
temp tables entirely.  Most folks recommend avoiding both of these and using
them only when necessary.


CREATE PROC MyProc (@tablename)
AS
CREATE TABLE #mytable (dt DATETIME)
EXEC ('INSERT #mytable SELECT max(col1) FROM ' + (@tablename)
EXEC ('INSERT #mytable SELECT min(col1) FROM ' + (@tablename)

SELECT * FROM #mytable
DROP TABLE #mytable
DROP VIEW #myview
RETURN 0.


Show quote
"Anatoli Dontsov" <Anat***@dontsov.com> wrote in message
news:%23JWq$C4eGHA.1436@TK2MSFTNGP05.phx.gbl...
> Hi, All!
>
> I have many tables with name convention tYYYYMMDD
> and set of SPs to perform some calculations.
>
> Ideally I would need "temporary view' functionality.
>
> CREATE PROC MyProc (@tablename)
> AS
> CREATE TABLE #mytable (dt DATETIME)
> EXEC ('CREATE VIEW #myview AS SELECT * FROM ' + tablebame)
> EXEC Calc1
> EXEC Calc2
> SELECT * FROM #mytable
> DROP TABLE #mytable
> DROP VIEW #myview
> RETURN 0.
>
>
> CREATE PROC Calc1
> AS
>  INSERT #mytable SELECT max(col1) FROM #myview
>
> CREATE PROC Calc2
> AS
>  INSERT #mytable SELECT min(col1) FROM #myview
>
>
> CalcX  - can be very complex and I got many of them.
>
> Unfortunately SQL doesn't support "temporary view'.
> Is there a workarround?
>
> Bye, Anatol
>
>
>
>
>
>
>
Author
22 May 2006 2:12 AM
Anatoli Dontsov
Jim,

the issue is very simple - table I need to query is parameter of SP.

CREATE TABLE t20060101 (dt DATETIME, id INT, Col1 INT, Col2 INT)
CREATE TABLE t20060102 (dt DATETIME, id INT, Col1 INT, Col2 INT)
CREATE TABLE t20060103 (dt DATETIME, id INT, Col1 INT, Col2 INT)
....
each daily table has dozens millions rows. dt+id is primary key
sample data ...
     INSERT t20060101 VALUES ( '2006/1/1 7:00', 1 ,0, 0  )
     INSERT t20060101 VALUES ( '2006/1/1 7:00', 2 ,0, 0  )
     INSERT t20060101 VALUES ( '2006/1/1 7:01', 1 ,0, 0  )
.... it doesn't matter acctually.

Dynamilc SQL works only when I do simple queries.
I need hundreds lines of t-sql  code (some data mining) and want
reorgananize that and divide into dozen simpler SPs.

Partitioned view is nice idea but has bad performance

CREATE VIEW MyView as
    SELECT * FROM t20060101
        UNION ALL
    SELECT * FROM t20060102
        UNION ALL
    SELECT * FROM t20060103
....

Bye, Anatoli




Show quote
"Jim Underwood" <james.underwoodATfallonclinic.com> wrote

> A"temporary view" would be a temporary table.  Use two temp tables to do
> what you need.
>
> However, I don't see why you need to use this view at all.  Why not just
> do
> this...
>
> Even better, post a full description of what you are trying to do,
> including
> DDL and sample data, and you may be able to eliminate the dynamic SQL and
> temp tables entirely.  Most folks recommend avoiding both of these and
> using
> them only when necessary.
>
>
> CREATE PROC MyProc (@tablename)
> AS
> CREATE TABLE #mytable (dt DATETIME)
> EXEC ('INSERT #mytable SELECT max(col1) FROM ' + (@tablename)
> EXEC ('INSERT #mytable SELECT min(col1) FROM ' + (@tablename)
>
> SELECT * FROM #mytable
> DROP TABLE #mytable
> DROP VIEW #myview
> RETURN 0.
>
>
> "Anatoli Dontsov" <Anat***@dontsov.com> wrote in message
> news:%23JWq$C4eGHA.1436@TK2MSFTNGP05.phx.gbl...
>> Hi, All!
>>
>> I have many tables with name convention tYYYYMMDD
>> and set of SPs to perform some calculations.
>>
>> Ideally I would need "temporary view' functionality.
>>
>> CREATE PROC MyProc (@tablename)
>> AS
>> CREATE TABLE #mytable (dt DATETIME)
>> EXEC ('CREATE VIEW #myview AS SELECT * FROM ' + tablebame)
>> EXEC Calc1
>> EXEC Calc2
>> SELECT * FROM #mytable
>> DROP TABLE #mytable
>> DROP VIEW #myview
>> RETURN 0.
>>
>>
>> CREATE PROC Calc1
>> AS
>>  INSERT #mytable SELECT max(col1) FROM #myview
>>
>> CREATE PROC Calc2
>> AS
>>  INSERT #mytable SELECT min(col1) FROM #myview
>>
>>
>> CalcX  - can be very complex and I got many of them.
>>
>> Unfortunately SQL doesn't support "temporary view'.
>> Is there a workarround?
>>
>> Bye, Anatol
>>
>>
>>
>>
>>
>>
>>
>
>
Author
24 May 2006 10:25 PM
Hugo Kornelis
On Sun, 21 May 2006 22:12:01 -0400, Anatoli Dontsov wrote:

(snip)
>Partitioned view is nice idea but has bad performance
>
>CREATE VIEW MyView as
>    SELECT * FROM t20060101
>        UNION ALL
>    SELECT * FROM t20060102
>        UNION ALL
>    SELECT * FROM t20060103

Hi Anatoli,

Based on the CREATE TABLE statements you posted, this is not a
partitioned view at all. It will only be a partitioned view (and gain
the advantages of it) if you add a CHECK constraint to the underlying
table, so that SQL Server knows what data lives in which table.

For instance:

CREATE TABLE t20060101
            (dt DATETIME NOT NULL,
             id INT NOT NULL,
             Col1 INT,
             Col2 INT,
             PRIMARY KKEY (dt, id),
             CHECK (dt >= '20060101' AND dt < '20060102')
            )

With that, a query against the partitioned view that includes a filter
on the dt column should only hit the table(s) with matching rows.

--
Hugo Kornelis, SQL Server MVP
Author
26 May 2006 2:58 AM
Anatoli Dontsov
Hi, Hugo.

I ommited CHECK and PK to not overload text.
I created partitioned view exaclty as described in BOL.
The resourses to select table to get data from are not 0 and for intensive
data mining performace penalty in visible.

the same SP accessing the first table in chain of tables in the view takes 2
minutes, and for the second table - 15 minutes.

Best regards, Anatoli


Show quote
"Hugo Kornelis" <h***@perFact.REMOVETHIS.info.INVALID> wrot


> Based on the CREATE TABLE statements you posted, this is not a
> partitioned view at all. It will only be a partitioned view (and gain
> the advantages of it) if you add a CHECK constraint to the underlying

> With that, a query against the partitioned view that includes a filter
> on the dt column should only hit the table(s) with matching rows.
Author
26 May 2006 10:06 PM
Hugo Kornelis
On Thu, 25 May 2006 22:58:59 -0400, Anatoli Dontsov wrote:

>Hi, Hugo.
>
>I ommited CHECK and PK to not overload text.
>I created partitioned view exaclty as described in BOL.
>The resourses to select table to get data from are not 0 and for intensive
>data mining performace penalty in visible.
>
>the same SP accessing the first table in chain of tables in the view takes 2
>minutes, and for the second table - 15 minutes.

Hi Anatoli,

A partitioned view should perform better than that.

Can you post the *exact* query you are using to query the data? Adding
the *exact* CREATE TABLE and CREATE VIEW statements would help as well.

Also, can you post the query plan of a query that takes too long?

--
Hugo Kornelis, SQL Server MVP
Author
26 May 2006 3:53 AM
Steve Kass
Anatoli,

Hugo has given you good advice, and I agree that
a partitioned view should have good performance.
It is not a good idea to use many tables with names
like tYYYYMMDD without a partitioned view

However, here is a suggestion if you cannot make the
partitioned view work correctly - use CONTEXT_INFO
to do the work of the partitioned view more directly.
Here is a repro script to give you the idea.

Warning: On my instance of SQL Server 2005, the
repro fails because some metadata is not cleared for
the database Anatoli I create for the script. So in 2005
add a statement to drop the temp table for the repro.
The repro should work in 2000, and in 2005, you would
want to use the new CONTEXT_INFO function anyway.

-- *** Don't run this if you have a database named Anatoli !!

use master
go
create database Anatoli
go
use Anatoli
go

create table T1 (i int primary key, d datetime)
create table T2 (i int primary key, d datetime)
create table T3 (i int primary key, d datetime)
create table T4 (i int primary key, d datetime)
insert into T1 values(1,getdate())
insert into T2 values(2,getdate())
insert into T3 values(3,getdate())
insert into T4 values(4,getdate())
go

create view aView as
select i, d from T1
where (
  select context_info from master.dbo.sysprocesses
  where spid = @@spid
) = cast('T1' as varbinary(20))
union all
select i, d from T2
where (
  select context_info from master.dbo.sysprocesses
  where spid = @@spid
) = cast('T2' as varbinary(20))
union all
select i, d from T3
where (
  select context_info from master.dbo.sysprocesses
  where spid = @@spid
) = cast('T3' as varbinary(20))
union all
select i, d from T4
where (
  select context_info from master.dbo.sysprocesses
  where spid = @@spid
) = cast('T4' as varbinary(20))
go

create table #temp(i int)
go

create proc Calc1 as
insert into #temp select max(i) from aView
go

DECLARE @tname VARBINARY(20)
SET @tname = CAST('T3' AS VARBINARY(20))
SET CONTEXT_INFO @tname
go

set statistics io on
exec Calc1
set statistics io off

select * from #temp
go
use master
go
drop database Anatoli
go




Anatoli Dontsov wrote:

Show quote
>Hi, All!
>
>I have many tables with name convention tYYYYMMDD
>and set of SPs to perform some calculations.
>
>Ideally I would need "temporary view' functionality.
>
>CREATE PROC MyProc (@tablename)
>AS
>CREATE TABLE #mytable (dt DATETIME)
>EXEC ('CREATE VIEW #myview AS SELECT * FROM ' + tablebame)
>EXEC Calc1
>EXEC Calc2
>SELECT * FROM #mytable
>DROP TABLE #mytable
>DROP VIEW #myview
>RETURN 0.
>
>
>CREATE PROC Calc1
>AS
> INSERT #mytable SELECT max(col1) FROM #myview
>
>CREATE PROC Calc2
>AS
> INSERT #mytable SELECT min(col1) FROM #myview
>
>
>CalcX  - can be very complex and I got many of them.
>
>Unfortunately SQL doesn't support "temporary view'.
>Is there a workarround?
>
>Bye, Anatol
>
>
>
>
>
>
>

>
Author
26 May 2006 3:59 AM
Steve Kass
Correction - the repro should have
DROP TABLE #temp
at the end, no matter what version of SQL Server you
are running.  I was not thinking when I added the Warning -
obviously #temp does not get dropped when the database
is dropped...

This should not affect the possibility of using this idea.

SK

Steve Kass wrote:

Show quote
> Anatoli,
>
> Hugo has given you good advice, and I agree that
> a partitioned view should have good performance.
> It is not a good idea to use many tables with names
> like tYYYYMMDD without a partitioned view
>
> However, here is a suggestion if you cannot make the
> partitioned view work correctly - use CONTEXT_INFO
> to do the work of the partitioned view more directly.
> Here is a repro script to give you the idea.
>
> Warning: On my instance of SQL Server 2005, the
> repro fails because some metadata is not cleared for
> the database Anatoli I create for the script. So in 2005
> add a statement to drop the temp table for the repro.
> The repro should work in 2000, and in 2005, you would
> want to use the new CONTEXT_INFO function anyway.
>
> -- *** Don't run this if you have a database named Anatoli !!
>
> use master
> go
> create database Anatoli
> go
> use Anatoli
> go
>
> create table T1 (i int primary key, d datetime)
> create table T2 (i int primary key, d datetime)
> create table T3 (i int primary key, d datetime)
> create table T4 (i int primary key, d datetime)
> insert into T1 values(1,getdate())
> insert into T2 values(2,getdate())
> insert into T3 values(3,getdate())
> insert into T4 values(4,getdate())
> go
>
> create view aView as
> select i, d from T1
> where (
>  select context_info from master.dbo.sysprocesses
>  where spid = @@spid
> ) = cast('T1' as varbinary(20))
> union all
> select i, d from T2
> where (
>  select context_info from master.dbo.sysprocesses
>  where spid = @@spid
> ) = cast('T2' as varbinary(20))
> union all
> select i, d from T3
> where (
>  select context_info from master.dbo.sysprocesses
>  where spid = @@spid
> ) = cast('T3' as varbinary(20))
> union all
> select i, d from T4
> where (
>  select context_info from master.dbo.sysprocesses
>  where spid = @@spid
> ) = cast('T4' as varbinary(20))
> go
>
> create table #temp(i int)
> go
>
> create proc Calc1 as
> insert into #temp select max(i) from aView
> go
>
> DECLARE @tname VARBINARY(20)
> SET @tname = CAST('T3' AS VARBINARY(20))
> SET CONTEXT_INFO @tname
> go
>
> set statistics io on
> exec Calc1
> set statistics io off
>
> select * from #temp
> go
> use master
> go
> drop database Anatoli
> go
>
>
>
>
> Anatoli Dontsov wrote:
>
>> Hi, All!
>>
>> I have many tables with name convention tYYYYMMDD
>> and set of SPs to perform some calculations.
>>
>> Ideally I would need "temporary view' functionality.
>>
>> CREATE PROC MyProc (@tablename)
>> AS
>> CREATE TABLE #mytable (dt DATETIME)
>> EXEC ('CREATE VIEW #myview AS SELECT * FROM ' + tablebame)
>> EXEC Calc1
>> EXEC Calc2
>> SELECT * FROM #mytable
>> DROP TABLE #mytable
>> DROP VIEW #myview
>> RETURN 0.
>>
>>
>> CREATE PROC Calc1
>> AS
>> INSERT #mytable SELECT max(col1) FROM #myview
>>
>> CREATE PROC Calc2
>> AS
>> INSERT #mytable SELECT min(col1) FROM #myview
>>
>>
>> CalcX  - can be very complex and I got many of them.
>>
>> Unfortunately SQL doesn't support "temporary view'.
>> Is there a workarround?
>>
>> Bye, Anatol
>>
>>
>>
>>
>>
>>
>>
>> 
>>
Author
26 May 2006 6:01 AM
oj
That's a very nice use of context_info, Steve! I would add to pick just one
row from sysprocesses ...paralellism can bite...;-)

where (
  select top 1 context_info from master.dbo.sysprocesses
  where spid = @@spid
) = cast('T2' as varbinary(20))


--
-oj



Show quote
"Steve Kass" <sk***@drew.edu> wrote in message
news:uuaoGgHgGHA.3916@TK2MSFTNGP04.phx.gbl...
> Anatoli,
>
> Hugo has given you good advice, and I agree that
> a partitioned view should have good performance.
> It is not a good idea to use many tables with names
> like tYYYYMMDD without a partitioned view
>
> However, here is a suggestion if you cannot make the
> partitioned view work correctly - use CONTEXT_INFO
> to do the work of the partitioned view more directly.
> Here is a repro script to give you the idea.
>
> Warning: On my instance of SQL Server 2005, the
> repro fails because some metadata is not cleared for
> the database Anatoli I create for the script. So in 2005
> add a statement to drop the temp table for the repro.
> The repro should work in 2000, and in 2005, you would
> want to use the new CONTEXT_INFO function anyway.
>
> -- *** Don't run this if you have a database named Anatoli !!
>
> use master
> go
> create database Anatoli
> go
> use Anatoli
> go
>
> create table T1 (i int primary key, d datetime)
> create table T2 (i int primary key, d datetime)
> create table T3 (i int primary key, d datetime)
> create table T4 (i int primary key, d datetime)
> insert into T1 values(1,getdate())
> insert into T2 values(2,getdate())
> insert into T3 values(3,getdate())
> insert into T4 values(4,getdate())
> go
>
> create view aView as
> select i, d from T1
> where (
>  select context_info from master.dbo.sysprocesses
>  where spid = @@spid
> ) = cast('T1' as varbinary(20))
> union all
> select i, d from T2
> where (
>  select context_info from master.dbo.sysprocesses
>  where spid = @@spid
> ) = cast('T2' as varbinary(20))
> union all
> select i, d from T3
> where (
>  select context_info from master.dbo.sysprocesses
>  where spid = @@spid
> ) = cast('T3' as varbinary(20))
> union all
> select i, d from T4
> where (
>  select context_info from master.dbo.sysprocesses
>  where spid = @@spid
> ) = cast('T4' as varbinary(20))
> go
>
> create table #temp(i int)
> go
>
> create proc Calc1 as
> insert into #temp select max(i) from aView
> go
>
> DECLARE @tname VARBINARY(20)
> SET @tname = CAST('T3' AS VARBINARY(20))
> SET CONTEXT_INFO @tname
> go
>
> set statistics io on
> exec Calc1
> set statistics io off
>
> select * from #temp
> go
> use master
> go
> drop database Anatoli
> go
>
>
Author
26 May 2006 1:23 PM
Steve Kass
Good point.  I should add that I've never tried this out
in production, but I'd be very interested to know if it
turns out to work well ... or not.  :|

SK

oj wrote:

Show quote
>That's a very nice use of context_info, Steve! I would add to pick just one
>row from sysprocesses ...paralellism can bite...;-)
>
>where (
>  select top 1 context_info from master.dbo.sysprocesses
>  where spid = @@spid
>) = cast('T2' as varbinary(20))
>
>

>

AddThis Social Bookmark Button