联合所有在 SQL Server 中的视图性能问题

Posted

技术标签:

【中文标题】联合所有在 SQL Server 中的视图性能问题【英文标题】:Union all in View Performance issue in SQL Server 【发布时间】:2017-05-14 10:03:33 【问题描述】:

我有 40 个表 - Table1、Table2、Table3 ... Table40,都有相同的列。 这些表包含不同的数据并识别每个表的数据,我有一列Reporting_Type,每个表都有不同的值。

例如:Table1 的列Reporting_Type 具有值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 中创建此视图?

如果有人觉得这个问题太幼稚,我们深表歉意。我是数据库新手。如果需要更多信息,请告诉我。

【问题讨论】:

这个表有索引吗? @gofr1 。不,先生。他们没有任何索引。 这可能是个问题。考虑添加索引。 dirty reads 也可能会有所帮助。尝试使用带有表提示WITH (NOLOCK)(例如FROM TABLE40 WITH (NOLOCK))的脏读或在运行视图时添加SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED。还可以查看索引视图 (msdn) 看看这个问题/答案***.com/questions/10025569/… 非常感谢先生的回答。但我不明白表上的索引如何帮助更快地查看数据,因为我没有使用“where”子句。这只是计划。从 table_name 查询中选择 *。 【参考方案1】:

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

-- 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  

我也推荐使用交叉应用,在***'s another thread中有解释

【讨论】:

以上是关于联合所有在 SQL Server 中的视图性能问题的主要内容,如果未能解决你的问题,请参考以下文章

从视图填充或创建表的 SQL Server 过程 - 性能问题

提高 sql server 2012 中的视图性能

CTE 中的 SQL Server 视图导致性能不佳

SQL Server 中的条件联合,直到到达特定日期

SQL Server 中的视图

SQL Server-聚焦使用视图若干限制/建议视图查询性能问题,你懵逼了?(二十五)