在SQL Server中查看性能问题中的所有联合

时间:2017-05-14 10:03:33

标签: sql-server performance view union-all

我有40个表 - 表1,表2,表3 ...表40,都具有相同的列。 这些表包含不同的数据,并且为了识别每个表的数据,我有一个列Reporting_Type,每个表具有不同的值。

例如:Reporting_Type的列Table1的值为Reportin_Type1,依此类推。

请注意,每张表包含2-3百万条记录。

我需要创建一个视图,它结合了所有表中的数据。

我只是简单地应用了UNION ALL并输入了以下查询:

CREATE VIEW ALL DATA 
AS
   SELECT 
       COLUMN1, COLUMN2, COLUMN3, REPORTING_TYPE ..., COLUMN 40 
   FROM 
       TABLE1

   UNION ALL

   SELECT 
       COLUMN1, COLUMN2, COLUMN3, REPORTING_TYPE ..., COLUMN 40 
   FROM 
       TABLE2

   UNION ALL 

   SELECT 
       COLUMN1, COLUMN2, COLUMN3, REPORTING_TYPE ..., COLUMN 40 
   FROM 
       TABLE3

   ....

   SELECT 
       COLUMN1, COLUMN2, COLUMN3, REPORTING_TYPE ..., COLUMN 40 
   FROM 
       TABLE40

上述查询需要花费大量时间从所有表中获取数据。

是否可以建议任何性能调优查询或在SQL Server 2012中创建此视图的任何其他方式?

道歉,如果有人发现这个问题太天真了。我是数据库新手。如果需要更多信息,请告诉我。

1 个答案:

答案 0 :(得分:0)

我建议在这些表上使用Clustered Indexes,所以在所有表​​中都应该有主键,如果有这些表的主键,尝试重建或重新组织索引,重建和重组你也可以参考下面的脚本。没有任何集群索引以及它将扫描但具有聚集索引的条件,您将获得更好的性能。

-- Make Sure you have write USE <databasename> statement before executing statement.  
-- USE <databasename>
SET NOCOUNT ON;  
DECLARE @objectid int;  
DECLARE @indexid int;  
DECLARE @partitioncount bigint;  
DECLARE @schemaname nvarchar(500);   
DECLARE @objectname nvarchar(500);   
DECLARE @indexname nvarchar(500);   
DECLARE @partitionnum bigint;  
DECLARE @partitions bigint;  
DECLARE @frag float;  
DECLARE @command nvarchar(4000);   
-- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function   
-- and convert object and index IDs to names.  
SELECT  
    object_id AS objectid,  
    index_id AS indexid,  
    partition_number AS partitionnum,  
    avg_fragmentation_in_percent AS frag  
INTO #work_to_do  
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED')  
WHERE index_id > 0;  

-- Declare the cursor for the list of partitions to be processed.  
DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do;  

-- Open the cursor.  
OPEN partitions;  

-- Loop through the partitions.  
WHILE (1=1)  
    BEGIN;  
        FETCH NEXT  
           FROM partitions  
           INTO @objectid, @indexid, @partitionnum, @frag;  
        IF @@FETCH_STATUS < 0 BREAK;  
        SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)  
        FROM sys.objects AS o  
        JOIN sys.schemas as s ON s.schema_id = o.schema_id  
        WHERE o.object_id = @objectid;  
        SELECT @indexname = QUOTENAME(name)  
        FROM sys.indexes  
        WHERE  object_id = @objectid AND index_id = @indexid;  
        SELECT @partitioncount = count (*)  
        FROM sys.partitions  
        WHERE object_id = @objectid AND index_id = @indexid;  

        -- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding.  
        IF @frag < 30.0  OR @frag >= 5.0
            SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';  
        IF @frag >= 30.0 OR @frag < 5.0 
            SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';  
        IF @partitioncount > 1  
            SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS nvarchar(10));  
        EXEC (@command);  
        PRINT N'Executed: ' + @command;  
    END;  

-- Close and deallocate the cursor.  
CLOSE partitions;  
DEALLOCATE partitions;  

-- Drop the temporary table.  
DROP TABLE #work_to_do;  
GO  

我还建议使用交叉申请,StackOverflow's another thread

中对此进行了解释