สร้างดัชนีออฟไลน์ใหม่บนตารางที่แบ่งพาร์ติชัน


9

ถ้าฉันตารางพาร์ทิชันด้วยntext, textหรือimageประเภทข้อมูลและสร้างดัชนีบนพาร์ติชันเดียวที่มีonline = offไม่ว่าล็อคตารางทั้งหมดหรือเพียงแค่พาร์ทิชันในคำถาม?

คำตอบ:


13

ฉันมีเวลาดูนี้และเนื่องจากฉันมีสคริปต์ตัวอย่างบางส่วนที่เขียนแล้วมันค่อนข้างง่ายที่จะตรวจสอบส่วนที่เหลือ ลองตั้งค่าแล้วดูผลลัพธ์ สิ่งนี้จะสร้างตารางและดัชนีที่แบ่งพาร์ติชันที่จำเป็น

CREATE PARTITION FUNCTION YourMom ( INT )
    AS RANGE LEFT FOR VALUES ( 1000000, 2000000, 3000000, 4000000, 5000000 );

CREATE PARTITION SCHEME YourDad
    AS PARTITION YourMom
    ALL TO ( [PRIMARY] );

CREATE TABLE dbo.YourAuntDebbie
(
    Id INT,
    StopUsingDeprecatedDataTypes NTEXT
) ON YourDad (Id);


DECLARE @counter INT = 1;
WHILE @counter < 6
    BEGIN

        RAISERROR('Run number: %d', 0, 1, @counter) WITH NOWAIT;

        INSERT dbo.YourAuntDebbie WITH ( TABLOCK ) ( Id, StopUsingDeprecatedDataTypes )
        SELECT TOP 1000000 x.n + CASE WHEN @counter = 1 THEN 0
                                      WHEN @counter = 2 THEN 1000000 
                                      WHEN @counter = 3 THEN 2000000 
                                      WHEN @counter = 4 THEN 3000000 
                                      WHEN @counter = 5 THEN 4000000 
                                      ELSE 0 
                                      END, 
                           REPLICATE(N'A', x.n % 10000)
        FROM   (   SELECT ROW_NUMBER() OVER ( ORDER BY @@ROWCOUNT ) AS n
                   FROM   sys.messages AS m
                   CROSS JOIN sys.messages AS m2 ) AS x;

        SET @counter += 1;

    END;

CREATE CLUSTERED INDEX ix_whatever
    ON dbo.YourAuntDebbie ( Id ) ON YourDad(Id);

นั่นให้พาร์ติชั่น 5 อันที่มี 1 ล้านแถวและพาร์ทิชันว่างหนึ่งอัน

SELECT OBJECT_NAME(p.object_id) AS table_name, p.partition_number, p.rows
FROM   sys.partitions AS p
WHERE  p.object_id = OBJECT_ID('dbo.YourAuntDebbie');

ตารางแฟนซี:

+----------------+------------------+---------+
|   table_name   | partition_number |  rows   |
+----------------+------------------+---------+
| YourAuntDebbie |                1 | 1000000 |
| YourAuntDebbie |                2 | 1000000 |
| YourAuntDebbie |                3 | 1000000 |
| YourAuntDebbie |                4 | 1000000 |
| YourAuntDebbie |                5 | 1000000 |
| YourAuntDebbie |                6 |       0 |
+----------------+------------------+---------+

นี่คือเซสชั่น XE ที่ฉันใช้เพื่อดูว่าการล็อกดัชนีที่สร้างใหม่ต้องการอะไร:

CREATE EVENT SESSION Locks
    ON SERVER
    ADD EVENT sqlserver.lock_acquired
    ( SET collect_resource_description = ( 1 )
     ACTION ( sqlserver.sql_text )
     WHERE (   sqlserver.equal_i_sql_unicode_string(sqlserver.database_name, N'Crap')
               AND package0.equal_uint64(sqlserver.session_id, ( 61 )))),
    ADD EVENT sqlserver.lock_released
    ( SET collect_resource_description = ( 1 )
     ACTION ( sqlserver.sql_text )
     WHERE (   sqlserver.database_name = N'Crap'
               AND sqlserver.session_id = ( 61 )))
    ADD TARGET package0.event_file
    ( SET filename = N'c:\temp\Locks' )
    WITH ( MAX_MEMORY = 4096KB,
           EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
           MAX_DISPATCH_LATENCY = 30 SECONDS,
           MAX_EVENT_SIZE = 0KB,
           MEMORY_PARTITION_MODE = NONE,
           TRACK_CAUSALITY = ON,
           STARTUP_STATE = OFF );
GO

เมื่อถึงตอนนั้นฉันสามารถสร้างพาร์ติชันขึ้นใหม่แล้วขุดลงใน XE

ALTER EVENT SESSION Locks ON SERVER STATE = START;

ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 1 WITH (ONLINE = OFF);
GO 

ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 2 WITH (ONLINE = OFF);
GO 

ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 3 WITH (ONLINE = OFF);
GO 

ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 4 WITH (ONLINE = OFF);
GO 

ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 5 WITH (ONLINE = OFF); 
GO 

ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 6 WITH (ONLINE = OFF);
GO 

ALTER EVENT SESSION Locks ON SERVER STATE = STOP;

ตอนนี้ฉันจะวางชิ้นส่วนย่อยของเหตุการณ์ XE ไว้ท้ายเพราะมันน่าเกลียดและไม่มีเหตุผลที่จะทำให้ทุกคนนั่งลงเพื่อดูผลลัพธ์ ฉันจะใช้ผลลัพธ์ของพาร์ติชันแรกเป็นตัวอย่าง แต่พวกเขาจะเหมือนกันในทั้ง 6 พาร์ติชันแม้กระทั่งพาร์ติชันที่ว่างเปล่า

ฉัน จำกัด ผลลัพธ์ของการอัปเดตเฉพาะล็อคระดับวัตถุเท่านั้น นี่เป็นสิ่งเดียวที่เราใส่ใจ

   +---------------+-------------------------+----------------+--------------+-------+------------------+--------+
|   EventName   |        EventDate        |   ObjectName   | ResourceType | Mode  | PARTITIONREBUILT | Events |
+---------------+-------------------------+----------------+--------------+-------+------------------+--------+
| lock_acquired | 2017-10-03 13:21:14.554 | YourAuntDebbie | OBJECT       | SCH_M | PARTITION = 1    |      1 |
| lock_acquired | 2017-10-03 13:21:14.554 | YourAuntDebbie | OBJECT       | SCH_S | PARTITION = 1    |      1 |
| lock_released | 2017-10-03 13:21:14.554 | YourAuntDebbie | OBJECT       | SCH_S | PARTITION = 1    |      1 |
| lock_acquired | 2017-10-03 13:21:14.603 | YourAuntDebbie | OBJECT       | S     | PARTITION = 1    |      6 |
| lock_acquired | 2017-10-03 13:21:14.603 | YourAuntDebbie | OBJECT       | SCH_S | PARTITION = 1    |     30 |
| lock_released | 2017-10-03 13:21:14.603 | YourAuntDebbie | OBJECT       | SCH_S | PARTITION = 1    |     24 |
| lock_released | 2017-10-03 13:21:14.867 | YourAuntDebbie | OBJECT       | SCH_M | PARTITION = 1    |      1 |
+---------------+-------------------------+----------------+--------------+-------+------------------+--------+

จากสิ่งที่ผมสามารถบอกได้สำหรับแต่ละพาร์ทิชันที่SCH-Mล็อคนำออกมาที่จุดเริ่มต้นของดัชนีสร้างและปล่อยออกมาในท้ายที่สุดบนโต๊ะ

ตัวอย่างเช่นถ้าฉันเรียกใช้พาร์ติชันเดียวที่สร้างใหม่ในการทำธุรกรรม:

BEGIN TRAN

ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 1 WITH (ONLINE = OFF);

--ROLLBACK

จากนั้นในหน้าต่าง SSMS อื่น:

SELECT *
FROM dbo.YourAuntDebbie AS yad
WHERE yad.Id = 6000000
AND 1 = (SELECT 1)

การเลือกถูกบล็อกจนกว่าฉันจะฆ่าการสร้างใหม่ เมื่อเสร็จสิ้นแผนแบบสอบถามจะแสดงการกำจัดพาร์ติชันที่เกิดขึ้นดังนั้นเฉพาะพาร์ติชัน 1 ที่ถูกสร้างขึ้นมาใหม่จะปรากฏขึ้นเพื่อให้มีผลกับทั้งตาราง

ถั่ว

หวังว่านี่จะช่วยได้!

ตอนนี้นี่คือรหัสการทำลายเซสชัน XE อันยิ่งใหญ่:

    CREATE TABLE #Locks
       (
         ID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
         WaitsXML XML 
       );

INSERT  #Locks
        ( WaitsXML )
SELECT    CONVERT(XML, event_data) AS TargetData
FROM      sys.fn_xe_file_target_read_file( 'c:\temp\Locks*.xel', NULL, NULL, NULL);

WITH locks
AS ( SELECT l.WaitsXML.value('(/event/@name)[1]', 'VARCHAR(128)') AS EventName,
            l.WaitsXML.value('(/event/@timestamp)[1]', 'DATETIME2(3)') AS EventDate,
            l.WaitsXML.value('(event/data[@name="object_id"]/value)[1]', 'NUMERIC') AS ObjectId,
            l.WaitsXML.value('(event/data[@name="resource_type"]/text)[1]', 'VARCHAR(128)') AS ResourceType,
            l.WaitsXML.value('(event/data[@name="mode"]/text)[1]', 'VARCHAR(128)') AS Mode,
            l.WaitsXML.value('(event/action[@name="sql_text"]/value)[1]', 'VARCHAR(128)') AS SQLText,
            l.WaitsXML
     FROM   #Locks AS l )
SELECT   locks.EventName,
         locks.EventDate,
         ISNULL(OBJECT_NAME(locks.ObjectId), 'Unknown') AS ObjectName,
         locks.ResourceType,
         locks.Mode,
         SUBSTRING(
             locks.SQLText,
             CHARINDEX('PARTITION', locks.SQLText),
             CHARINDEX('WITH', locks.SQLText, CHARINDEX('PARTITION', locks.SQLText))
             - CHARINDEX('PARTITION', locks.SQLText)) AS PARTITIONREBUILT,
         COUNT(*) AS Events
FROM     locks
WHERE    OBJECT_NAME(locks.ObjectId) = 'YourAuntDebbie'
         --OR OBJECT_NAME(locks.ObjectId) IS NULL
GROUP BY ISNULL(OBJECT_NAME(locks.ObjectId), 'Unknown'),
         SUBSTRING(
             locks.SQLText,
             CHARINDEX('PARTITION', locks.SQLText),
             CHARINDEX('WITH', locks.SQLText, CHARINDEX('PARTITION', locks.SQLText))
             - CHARINDEX('PARTITION', locks.SQLText)),
         locks.EventName,
         locks.EventDate,
         locks.ResourceType,
         locks.Mode
ORDER BY locks.EventDate;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.