AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 154766
Accepted
mendosi
mendosi
Asked: 2016-11-10 17:29:57 +0800 CST2016-11-10 17:29:57 +0800 CST 2016-11-10 17:29:57 +0800 CST

用于禁用数据仓库负载的约束和索引的脚本

  • 772

我将数据加载到数据仓库中。

目前,为了方便和速度,我有一个脚本用于在加载数据之前删除外键约束和索引。有一个很大的窗口可以进行加载,所以我不需要担心用户在加载期间访问数据,但我不想影响数据库中其他表中不相关的数据。

我已经在这里和其他地方进行了一些研究以提出这个脚本,但我想知道是否有一些我可能会忽略的事情可能会导致性能次优或者我可能会遗漏一些重要的东西(我不知道. ..计算列或其他东西?)或者我做事的顺序错误等等。

任何建议都可以使这个强大和高性能。

禁用约束和索引

编辑:我删除了WHILE评论者帮助我意识到的循环是多余的。

Declare @schema varchar(128) = 'dbo';
Declare @sql nvarchar(max) = N'';

-- 1. Indices
-- Select a list of indexes in the schema and generate statements to disable them.
Select @sql = @sql + 'ALTER INDEX ' + QuoteName(idx.name) + ' ON ' + QuoteName(@schema) + '.' + QuoteName(obj.name) + ' DISABLE;' + CHAR(13)
  From sys.indexes As idx
  Join sys.objects As obj On idx.object_id = obj.object_id
  Where ((obj.type = 'U' And idx.type in (2,6)) -- Non-clustered index/columnstore on a table
    Or obj.type = 'V') -- All indexes on indexed views
    And obj.schema_id = (Select schema_id From sys.schemas Where name = @schema)
  Order By obj.name, idx.name;

Execute sp_executesql @sql;


-- 2. Foreign-key constraints
-- Build a list of foreign keys constraints in the schema and generate statements to disable the constraint checking.
Select @sql = @sql + 'ALTER TABLE ' + QuoteName(@schema) + '.' + QuoteName(obj.name) + ' NOCHECK CONSTRAINT ' + QuoteName(fk.name) + ';' + CHAR(13)
  From sys.foreign_keys As fk
  Join sys.objects As obj On fk.parent_object_id = obj.object_id  
  Where obj.schema_id = (Select schema_id From sys.schemas Where name = @schema);

Execute sp_executesql @sql;

启用约束、重建索引和更新统计信息

Declare @schema nvarchar(128) = 'dbo';
Declare @sql nvarchar(max) = N'';

-- 1. Indices
-- Build a list of tables in the schema and generate statements to enable the indices on them.
Select @sql = @sql + 'ALTER INDEX ' + QuoteName(idx.name) + ' ON ' + QuoteName(@schema) + '.' + QuoteName(obj.name) + ' REBUILD' + iif(idx.type = 6, ' WITH (MAXDOP = 1);', ' WITH (FILLFACTOR = 100);') + CHAR(13)
  From sys.indexes idx
  Join sys.objects obj ON obj.object_id = idx.object_id
  Where ((obj.type = 'U' And idx.type in (2,6)) -- Non-clustered index on a table
    Or obj.type = 'V') -- All indexes on indexed views
    And obj.schema_id = (Select schema_id From sys.schemas Where name = @schema)
    And idx.is_disabled = 1 -- Don't rebuild indexes that are already online
    And idx.is_hypothetical = 0 -- Don't rebuild hypothetical indexes!
  Order By iif(idx.type = 6, 1, 2), obj.name, idx.name;

Execute sp_executesql @sql;


-- 2. Foreign-key constraints
-- Build a list of foreign keys constraints in the schema and generate statements to enable them with checking.
Select @sql = @sql + 'ALTER TABLE ' + QuoteName(@schema) + '.' + QuoteName(obj.name) + ' WITH CHECK CHECK CONSTRAINT ' + QuoteName(fk.name) + ';' + CHAR(13)
  From sys.foreign_keys fk
  Join sys.objects obj ON obj.object_id = fk.parent_object_id
  Where obj.schema_id = (Select schema_id From sys.schemas Where name = @schema)
  Order By obj.name, fk.name;

Execute sp_executesql @sql;


-- 3. Statistics
-- Build a list of tables in the schema and generate statements to update the statistics on them.
Select @sql = @sql + 'UPDATE STATISTICS ' + QuoteName(@schema) + '.' + QuoteName(obj.name) + ' WITH COLUMNS;' + CHAR(13)
  From sys.objects obj
  Where obj.type = 'U' -- User defined
    AND obj.schema_id = (Select schema_id From sys.schemas Where name = @schema)
  Order By obj.name;

Execute sp_executesql @sql;
sql-server index
  • 4 4 个回答
  • 1908 Views

4 个回答

  • Voted
  1. Best Answer
    Joe Obbish
    2016-11-16T17:34:54+08:002016-11-16T17:34:54+08:00

    对于一些你可能没有考虑过的事情:

    1. 如果索引以禁用状态开始,您将在脚本完成后重新构建它。
    2. 如果索引以页面压缩开始,您将在不压缩的情况下重建它。

    对于性能:

    1. 由于没有其他进程正在访问该表,因此您可以使用该选项进行重建,ONLINE = OFF以减少锁定,从而可能提高性能。
    2. 根据 tempdb 的大小和您的索引,您可以使用该SORT_IN_TEMPDB = ON选项来提高性能。
    3. 您正在更新所有表的统计信息,即使该表尚未修改或更改的行数很少。您可以尝试在更新中更加严格,并且只查看自上次更新或完全修改过的统计信息以来修改过的表。
    4. 看起来您正在一个会话中运行所有这些查询。您是否考虑过在多个会话之间拆分工作?
    • 5
  2. Kin Shah
    2016-11-14T16:34:29+08:002016-11-14T16:34:29+08:00

    在您的情况下,在加载数据之前禁用外键有点令人担忧,因为当您启用它们时,您的脚本没有任何错误处理TRY .. CATCH blocks......

    加载数据后,您如何检查数据库的引用完整性?简单地启用外键并不能保证数据库的引用完整性。您至少应该运行DBCC CHECKCONSTRAINTS并确保它运行干净。参考:外键及其状态

    我看到的另一点是双重工作 - 重建索引后更新统计数据有什么意义?

    请记住,重建索引将更新与该索引关联的列的统计信息。

    有一个很大的窗口可以进行加载,所以我不需要担心用户在加载期间访问数据,但我不想影响数据库中其他表中不相关的数据。

    我强烈建议您阅读The Data Loading Performance Guide和我的回答中提到的各种技术。

    • 4
  3. Duane Lawrence
    2016-11-10T19:18:45+08:002016-11-10T19:18:45+08:00

    注意假设的指数。如果调优工具因为崩溃并且没有删除它们而留下它们,那么您的脚本将使它们成为真实的,现在您将在单个表上拥有 30 或 40 个索引,并且该表上的性能将充满阻塞和死锁.

    SELECT dbid = DB_ID(),
           objectid = object_id,
           indid = index_id
    FROM sys.indexes
    WHERE is_hypothetical = 1 ;
    
    • 2
  4. mendosi
    2016-12-05T18:39:15+08:002016-12-05T18:39:15+08:00

    这是我在整合了来自不同受访者的反馈之后的最终脚本(只是想将它们收集在一起以供将来的读者使用):

    禁用约束和索引

    Declare @schema varchar(128) = 'dbo';
    Declare @sql nvarchar(max) = '';
    
    -- 1. Indices
    -- Select a list of indexes in the schema and generate statements to disable them.
    Select @sql = @sql + 'ALTER INDEX ' + QuoteName(idx.name) + ' ON ' + QuoteName(@schema) + '.' + QuoteName(obj.name) + ' DISABLE;' + CHAR(13)
      From sys.indexes As idx
      Join sys.objects As obj On idx.object_id = obj.object_id
      Where ((obj.type = 'U' And idx.type in (2,6)) -- Non-clustered index/columnstore on a table
        Or obj.type = 'V') -- All indexes on indexed views
        And obj.schema_id = (Select schema_id From sys.schemas Where name = @schema)
      Order By obj.name, idx.name;
    
    Execute sp_executesql @sql;
    
    
    -- 2. Foreign-key constraints
    -- Build a list of foreign keys constraints in the schema and generate statements to disable the constraint checking.
    Select @sql = @sql + 'ALTER TABLE ' + QuoteName(@schema) + '.' + QuoteName(obj.name) + ' NOCHECK CONSTRAINT ' + QuoteName(fk.name) + ';' + CHAR(13)
      From sys.foreign_keys As fk
      Join sys.objects As obj On fk.parent_object_id = obj.object_id  
      Where obj.schema_id = (Select schema_id From sys.schemas Where name = @schema);
    
    Execute sp_executesql @sql;
    

    ** 重建索引、启用约束和更新统计信息**

    Declare @schema varchar(128) = 'dbo';
    Declare @sql nvarchar(max) = '';
    
    -- 1. Indices
    -- Build a list of tables in the schema and generate statements to enable the indices on them.
    Select @sql = @sql + 'ALTER INDEX ' + QuoteName(idx.name) + ' ON ' + QuoteName(@schema) + '.' + QuoteName(obj.name) + 
        ' REBUILD WITH (' + iif(idx.type = 6, 
                                'MAXDOP = 1', 
                                'FILLFACTOR = 100, DATA_COMPRESSION = ' + IsNull(p.data_compression_desc Collate Latin1_General_CI_AS, 'None') + ', ONLINE = OFF, SORT_IN_TEMPDB = ON') 
                        + ');' + CHAR(13)
      From sys.indexes idx
      Join sys.objects obj ON obj.object_id = idx.object_id
      Left Join sys.partitions As p On idx.object_id = p.object_id And idx.index_id = p.index_id
      Where ((obj.type = 'U' And idx.type in (2,6)) -- Non-clustered index on a table
        Or obj.type = 'V') -- All indexes on indexed views
        And obj.schema_id = (Select schema_id From sys.schemas Where name = @schema)
        And idx.is_disabled = 1 -- Don't rebuild indexes that are already online
        And idx.is_hypothetical = 0 -- Don't rebuild hypothetical indexes!
      Order By iif(idx.type = 6, 1, 2), obj.name, idx.name;
    
    Execute sp_executesql @sql;
    
    
    -- 2. Foreign-key constraints
    -- Build a list of foreign keys constraints in the schema and generate statements to enable them with checking.
    Select @sql = @sql + 'ALTER TABLE ' + QuoteName(@schema) + '.' + QuoteName(obj.name) + ' WITH CHECK CHECK CONSTRAINT ' + QuoteName(fk.name) + ';' + CHAR(13)
      From sys.foreign_keys fk
      Join sys.objects obj ON obj.object_id = fk.parent_object_id
      Where obj.schema_id = (Select schema_id From sys.schemas Where name = @schema)
      Order By obj.name, fk.name;
    
    --DBCC CheckConstraints('fForeignKey_Table'); -- Does a soft check of the constraints and returns any values which violate them.
    Execute sp_executesql @sql;
    
    
    -- 3. Statistics
    -- Build a list of tables in the schema and generate statements to update the statistics on them.
    Select @sql = @sql + 'UPDATE STATISTICS ' + QuoteName(@schema) + '.' + QuoteName(obj.name) + ' WITH COLUMNS;' + CHAR(13)
      From sys.objects obj
      Where obj.type = 'U' -- User defined
        AND obj.schema_id = (Select schema_id From sys.schemas Where name = @schema)
      Order By obj.name;
    
    Execute sp_executesql @sql;
    
    • 1

相关问题

  • 死锁的主要原因是什么,可以预防吗?

  • 我在索引上放了多少“填充”?

  • 如何确定是否需要或需要索引

  • RDBMS 上的“索引”是什么意思?[关闭]

  • 如何在 MySQL 中创建条件索引?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve