• 【SQLServer BUG?无图无真相!】SQLServer分区表的应用


      今天晚上兄弟遇到个奇怪的问题,查询一个表的ID可以显示出来,查询其他的列却查不出来了,如下图:

      我的第一反应是BillCode是char类型的,后面应该带空格了,所以让他用BillCode like '%CK201012718200850%' 去查下。

    结果被告知没查到,所以问他要了数据库地址和账号密码,自己去尝试了,果真如此。

      然后我查询了所有的数据,这个表一共只有到iID = 12372的记录。那12372以后的记录12386怎么出来的?第一反应是BUG(无知的汗颜。。。)

      然后我用12372试验了,如下语句,查到了12372是表的临界点。

      

      当时看到这个记录的时候,我承认我开始蛋疼了。。。我认为这个世界上还是有鬼的!(又为自己的无知汗颜一下。。。)

      说实话,我当时先是想办法怎么去解决他,所以很容易就找到了。用 iID<=12372 和 iID>=12373进行了查询。如下。

      

      兄弟说,是一个方法,但是需要修改很多。所以我们为了发现这一奇特的BUG,而继续探寻着。。这时兄弟在群里发了一张图。他咋发现的,我也不晓得。据说是他们外包的公司提供的。

      

      FUNCTION我知道,但这个 Partiton是何意思就不得而知了,上网搜了下,在百度文档里看到了“分区表”三个字,在这就恍然大悟了。原来一切都是这个“函数”在作怪。

      在文档上有这么一句话。

      

      在MSDN查询Partition的资料 用了一个T-SQL语句查到了根本。

      

    SELECT * FROM sys.partition_functions
    

      看到了这个造孽的分区,直接删除搞定。

    DROP PARTITION FUNCTION xBillIndexCust
    

      下面是别人整理的一些分区表的创建,合并,删除,查询的一些操作,在这做个备份吧。看博客园没有分区表的相关资料。

      

    --=========================================
    -- 转换为分区表
    --=========================================
    -- 1. 创建分区函数
    --    a. 适用于存储历史存档记录的分区表的分区函数
    DECLARE @dt datetime
    SET @dt = '20020101'
    CREATE PARTITION FUNCTION PF_HistoryArchive(datetime)
    AS RANGE RIGHT
    FOR VALUES(
        @dt,
        DATEADD(Year, 1, @dt))
     
    --    b. 适用于存储历史记录的分区表的分区函数
    --DECLARE @dt datetime
    SET @dt = '20000101'
    CREATE PARTITION FUNCTION PF_History(datetime)
    AS RANGE RIGHT
    FOR VALUES(
        @dt,
    DATEADD(Month, 1, @dt),
    DATEADD(Month, 2, @dt),
    DATEADD(Month, 3, @dt),
    DATEADD(Month, 4, @dt),
    DATEADD(Month, 5, @dt),
    DATEADD(Month, 6, @dt),
    DATEADD(Month, 7, @dt),
    DATEADD(Month, 8, @dt),
    DATEADD(Month, 9, @dt),
    DATEADD(Month, 10, @dt),
    DATEADD(Month, 11, @dt),
    DATEADD(Month, 12, @dt))
    GO
     
    -- 2. 创建分区架构
    --    a. 适用于存储历史存档记录的分区表的分区架构
    CREATE PARTITION SCHEME PS_HistoryArchive
    AS PARTITION PF_HistoryArchive
    TO([PRIMARY], [PRIMARY], [PRIMARY])
     
    --    b. 适用于存储历史记录的分区表的分区架构
    CREATE PARTITION SCHEME PS_History
    AS PARTITION PF_History
    TO([PRIMARY], [PRIMARY],
        [PRIMARY], [PRIMARY], [PRIMARY],
        [PRIMARY], [PRIMARY], [PRIMARY],
        [PRIMARY], [PRIMARY], [PRIMARY],
        [PRIMARY], [PRIMARY], [PRIMARY])
    GO
     
    -- 3. 删除索引
    --    a. 删除存储历史存档记录的表中的索引
    DROP INDEX Production.TransactionHistoryArchive.IX_TransactionHistoryArchive_ProductID
    DROP INDEX Production.TransactionHistoryArchive.IX_TransactionHistoryArchive_ReferenceOrderID_ReferenceOrderLineID
     
    --    b. 删除存储历史记录的表中的索引
    DROP INDEX Production.TransactionHistory.IX_TransactionHistory_ProductID
    DROP INDEX Production.TransactionHistory.IX_TransactionHistory_ReferenceOrderID_ReferenceOrderLineID
    GO
     
    -- 4. 转换为分区表
    --    a. 将存储历史存档记录的表转换为分区表
    ALTER TABLE Production.TransactionHistoryArchive
        DROP CONSTRAINT PK_TransactionHistoryArchive_TransactionID
        WITH(
            MOVE TO PS_HistoryArchive(TransactionDate))
     
    --    b.将存储历史记录的表转换为分区表
    ALTER TABLE Production.TransactionHistory
        DROP CONSTRAINT PK_TransactionHistory_TransactionID
        WITH(
            MOVE TO PS_History(TransactionDate))
    GO
     
    -- 5. 恢复主键
    --    a. 恢复存储历史存档记录的分区表的主键
    ALTER TABLE Production.TransactionHistoryArchive
        ADD CONSTRAINT PK_TransactionHistoryArchive_TransactionID
            PRIMARY KEY CLUSTERED(
                TransactionID,
                TransactionDate)
     
    --    b. 恢复存储历史记录的分区表的主键
    ALTER TABLE Production.TransactionHistory
        ADD CONSTRAINT PK_TransactionHistory_TransactionID
            PRIMARY KEY CLUSTERED(
                TransactionID,
                TransactionDate)
    GO
    -- 6. 恢复索引
    --    a. 恢复存储历史存档记录的分区表的索引
    CREATE INDEX IX_TransactionHistoryArchive_ProductID
        ON Production.TransactionHistoryArchive(
            ProductID)
     
    CREATE INDEX IX_TransactionHistoryArchive_ReferenceOrderID_ReferenceOrderLineID
        ON Production.TransactionHistoryArchive(
            ReferenceOrderID,
            ReferenceOrderLineID)
     
    --    b. 恢复存储历史记录的分区表的索引
    CREATE INDEX IX_TransactionHistory_ProductID
        ON Production.TransactionHistory(
            ProductID)
     
    CREATE INDEX IX_TransactionHistory_ReferenceOrderID_ReferenceOrderLineID
        ON Production.TransactionHistory(
            ReferenceOrderID,
            ReferenceOrderLineID)
    GO
    -- 7. 查看分区表的相关信息
    SELECT
        SchemaName = S.name,
        TableName = TB.name,
        PartitionScheme = PS.name,
        PartitionFunction = PF.name,
        PartitionFunctionRangeType = CASE
                WHEN boundary_value_on_right = 0 THEN 'LEFT'
                ELSE 'RIGHT' END,
        PartitionFunctionFanout = PF.fanout,
        SchemaID = S.schema_id,
        ObjectID = TB.object_id,
        PartitionSchemeID = PS.data_space_id,
        PartitionFunctionID = PS.function_id
    FROM sys.schemas S
        INNER JOIN sys.tables TB
            ON S.schema_id = TB.schema_id
        INNER JOIN sys.indexes IDX
            on TB.object_id = IDX.object_id
                AND IDX.index_id < 2
        INNER JOIN sys.partition_schemes PS
            ON PS.data_space_id = IDX.data_space_id
        INNER JOIN sys.partition_functions PF
            ON PS.function_id = PF.function_id
    GO
     
    --=========================================
    -- 移动分区表数据
    --=========================================
    -- 1. 为存储历史存档记录的分区表增加分区, 并接受从历史记录分区表移动过来的数据
    --    a. 修改分区架构, 增加用以接受新分区的文件组
    ALTER PARTITION SCHEME PS_HistoryArchive
    NEXT USED [PRIMARY]
     
    --    b. 修改分区函数, 增加分区用以接受从历史记录分区表移动过来的数据
    DECLARE @dt datetime
    SET @dt = '20030901'
    ALTER PARTITION FUNCTION PF_HistoryArchive()
    SPLIT RANGE(@dt)
     
    --    c. 将历史记录表中的过期数据移动到历史存档记录表中
    ALTER TABLE Production.TransactionHistory
        SWITCH PARTITION 2
            TO Production.TransactionHistoryArchive PARTITION $PARTITION.PF_HistoryArchive(@dt)
     
    --    d. 将接受到的数据与原来的分区合并
    ALTER PARTITION FUNCTION PF_HistoryArchive()
    MERGE RANGE(@dt)
    GO
     
    -- 2. 将存储历史记录的分区表中不包含数据的分区删除, 并增加新的分区以接受新数据
    --    a. 合并不包含数据的分区
    DECLARE @dt datetime
    SET @dt = '20030901'
    ALTER PARTITION FUNCTION PF_History()
    MERGE RANGE(@dt)
     
    --    b.  修改分区架构, 增加用以接受新分区的文件组
    ALTER PARTITION SCHEME PS_History
    NEXT USED [PRIMARY]
     
    --    c. 修改分区函数, 增加分区用以接受新数据
    SET @dt = '20041001'
    ALTER PARTITION FUNCTION PF_History()
    SPLIT RANGE(@dt)
    GO
     
     
    --=========================================
    -- 清除历史存档记录中的过期数据
    --=========================================
    -- 1. 创建用于保存过期的历史存档数据的表
    CREATE TABLE Production.TransactionHistoryArchive_2001_temp(
        TransactionID int NOT NULL,
        ProductID int NOT NULL,
        ReferenceOrderID int NOT NULL,
        ReferenceOrderLineID int NOT NULL
            DEFAULT ((0)),
        TransactionDate datetime NOT NULL
            DEFAULT (GETDATE()),
        TransactionType nchar(1) NOT NULL,
        Quantity int NOT NULL,
        ActualCost money NOT NULL,
        ModifiedDate datetime NOT NULL
            DEFAULT (GETDATE()),
        CONSTRAINT PK_TransactionHistoryArchive_2001_temp_TransactionID
            PRIMARY KEY CLUSTERED(
                TransactionID,
                TransactionDate)
    )
     
    -- 2. 将数据从历史存档记录分区表移动到第步创建的表中
    ALTER TABLE Production.TransactionHistoryArchive
        SWITCH PARTITION 1
            TO Production.TransactionHistoryArchive_2001_temp
     
    -- 3. 删除不再包含数据的分区
    DECLARE @dt datetime
    SET @dt = '20020101'
    ALTER PARTITION FUNCTION PF_HistoryArchive()
    MERGE RANGE(@dt)
     
    -- 4. 修改分区架构, 增加用以接受新分区的文件组
    ALTER PARTITION SCHEME PS_HistoryArchive
    NEXT USED [PRIMARY]
     
    -- 5. 修改分区函数, 增加分区用以接受新数据
    SET @dt = '20040101'
    ALTER PARTITION FUNCTION PF_HistoryArchive()
    SPLIT RANGE(@dt)
    
  • 相关阅读:
    [bug] ERROR: Can't get master address from ZooKeeper; znode data == null
    [面试] 大数据
    [项目] 智慧出行
    [Linux] grep -v
    [Linux] > /dev/null 2>&1 &
    [bug] CDH报错:cloudera-scm-server dead but pid file exists
    [bug] CM / CDH 主机运行状态不良情况
    [bug] org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 2
    [其他] 记忆的奥秘(一)
    处理数字的类 —— Math类 、 Random类 、 BigDecimal类 与 BigInteger类
  • 原文地址:https://www.cnblogs.com/tweet/p/1899534.html
Copyright © 2020-2023  润新知