เหตุใดจึงใช้ทั้ง TRUNCATE และ DROP


100

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

เพื่อนร่วมงานของฉันหลายคน (เกือบทุกคนมีประสบการณ์มากกว่าฉัน) โดยทั่วไปแล้วทำสิ่งนี้:

TRUNCATE TABLE #mytemp
DROP TABLE #mytemp

ฉันมักจะใช้ซิงเกิ้ลDROP TABLEในสคริปท์ของฉัน

มีเหตุผลที่ดีในการทำTRUNCATEทันทีก่อนDROP?

คำตอบ:


130

เลขที่

TRUNCATEและDROPเกือบจะเหมือนกันในพฤติกรรมและความเร็วดังนั้นการทำสิ่งที่TRUNCATEถูกต้องก่อนสิ่งที่DROPไม่จำเป็น


หมายเหตุ: ฉันเขียนคำตอบนี้จากมุมมอง SQL Server และคิดว่ามันจะใช้กับ Sybase อย่างเท่าเทียมกัน ปรากฏว่านี่ไม่ใช่กรณีทั้งหมด

หมายเหตุ: เมื่อฉันโพสต์คำตอบนี้เป็นครั้งแรกมีคำตอบที่ได้รับการจัดอันดับสูงอื่น ๆ รวมถึงคำตอบที่ยอมรับแล้วซึ่งทำให้การอ้างสิทธิ์ที่ผิดพลาดหลายประการเช่น: TRUNCATEไม่ถูกบันทึก; TRUNCATEไม่สามารถย้อนกลับได้ TRUNCATEจะเร็วกว่าDROP; เป็นต้น

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


มีความเท็จที่เป็นที่นิยมอยู่สองสามอย่างที่แพร่หลายแม้กระทั่งใน DBA ที่มีประสบการณ์ซึ่งอาจเป็นแรงบันดาลใจให้กับTRUNCATE-then-DROPรูปแบบนี้ พวกเขาคือ:

  • ตำนาน : TRUNCATEไม่ได้ถูกบันทึกดังนั้นจึงไม่สามารถย้อนกลับได้
  • ตำนาน : จะเร็วกว่าTRUNCATEDROP

ผมขอโต้แย้งความเท็จเหล่านี้ ฉันกำลังเขียนการโต้แย้งนี้จากมุมมองของ SQL Server แต่ทุกสิ่งที่ฉันพูดที่นี่ควรจะใช้ได้กับ Sybase อย่างเท่าเทียมกัน

TRUNCATE ถูกบันทึกและสามารถย้อนกลับได้

  • TRUNCATEคือการดำเนินการเข้าสู่ระบบเพื่อให้มันสามารถจะย้อนกลับ เพียงห่อไว้ในธุรกรรม

    USE [tempdb];
    SET NOCOUNT ON;
    
    CREATE TABLE truncate_demo (
        whatever    VARCHAR(10)
    );
    
    INSERT INTO truncate_demo (whatever)
    VALUES ('log this');
    
    BEGIN TRANSACTION;
        TRUNCATE TABLE truncate_demo;
    ROLLBACK TRANSACTION;
    
    SELECT *
    FROM truncate_demo;
    
    DROP TABLE truncate_demo;
    

    แต่โปรดทราบว่านี้คือไม่เป็นความจริงสำหรับ Oracle แม้ว่าจะได้รับการบันทึกและป้องกันโดยฟังก์ชันการเลิกทำและทำซ้ำของ Oracle และTRUNCATEคำสั่ง DDL อื่น ๆไม่สามารถย้อนกลับได้โดยผู้ใช้เนื่องจากปัญหาของ Oracle กระทำโดยปริยายทันทีก่อนและหลังคำสั่ง DDL ทั้งหมด

  • TRUNCATEถูกบันทึกน้อยที่สุดซึ่งต่างจากการเข้าสู่ระบบอย่างสมบูรณ์ นั่นหมายความว่าอย่างไร? พูดTRUNCATEถึงตาราง แทนที่จะใส่แต่ละแถวที่ถูกลบในบันทึกการทำธุรกรรมTRUNCATEเพียงทำเครื่องหมายหน้าข้อมูลที่พวกเขาอาศัยอยู่เป็นไม่ได้ปันส่วน นั่นเป็นเหตุผลที่มันเร็วมาก นั่นเป็นสาเหตุที่คุณไม่สามารถกู้คืนแถวของTRUNCATEตารางที่บันทึกจากบันทึกธุรกรรมโดยใช้เครื่องอ่านบันทึก คุณจะพบว่ามีการอ้างอิงไปยังหน้าข้อมูลที่ถูกจัดสรรคืน

    DELETEเปรียบเทียบนี้เพื่อ หากคุณDELETEแถวทั้งหมดในตารางและยอมรับธุรกรรมที่คุณสามารถทำได้ในทางทฤษฎีค้นหาแถวที่ถูกลบในบันทึกธุรกรรมและกู้คืนจากที่นั่น นั่นเป็นเพราะDELETEเขียนทุกแถวที่ถูกลบไปยังบันทึกการทำธุรกรรม สำหรับตารางขนาดใหญ่สิ่งนี้จะทำให้ช้ากว่าTRUNCATEมาก

DROPเร็วพอ ๆ กับ TRUNCATE

  • เช่นTRUNCATE, DROPคือการดำเนินการลงทะเบียนน้อยที่สุด นั่นหมายความว่าDROPสามารถย้อนกลับได้เช่นกัน นั่นก็หมายความว่าการทำงานตรงเช่นเดียวกับTRUNCATEเป็น แทนการลบแถวแต่ละเครื่องหมายหน้าข้อมูลที่เหมาะสมตามที่ได้ถูกจัดสรรและยังนับเป็นข้อมูลเมตาของตารางเป็นลบDROP
  • เพราะTRUNCATEและDROPทำงานในลักษณะเดียวกันพวกเขาก็วิ่งเร็วเหมือนกัน ไม่มีประเด็นในTRUNCATEการตารางก่อนที่DROPจะทำการ เรียกใช้สคริปต์สาธิตนี้ในอินสแตนซ์การพัฒนาของคุณหากคุณไม่เชื่อฉัน

    ในเครื่องของฉันที่มีแคชอุ่นผลลัพธ์ที่ฉันได้รับมีดังนี้:

    table row count: 134,217,728
    
    run#        transaction duration (ms)
          TRUNCATE   TRUNCATE then DROP   DROP
    ==========================================
    01       0               1             4
    02       0              39             1
    03       0               1             1
    04       0               2             1
    05       0               1             1
    06       0              25             1
    07       0               1             1
    08       0               1             1
    09       0               1             1
    10       0              12             1
    ------------------------------------------
    avg      0              8.4           1.3
    

    ดังนั้นสำหรับตาราง134 ล้านแถวทั้งคู่DROPและไม่TRUNCATEต้องใช้เวลาอย่างมีประสิทธิภาพเลย (ในแคชเย็นพวกเขาใช้เวลาประมาณ 2-3 วินาทีในการรันครั้งแรกหรือสองครั้ง) ฉันยังเชื่อว่าระยะเวลาเฉลี่ยที่สูงขึ้นสำหรับการดำเนินการTRUNCATEนั้นนั้นเกิดจากDROPการโหลดรูปแบบต่าง ๆ บนเครื่องท้องถิ่นของฉันและไม่ใช่เพราะการรวมกันนั้น ลำดับความรุนแรงยิ่งกว่าการปฏิบัติการเดี่ยว พวกเขาเกือบทั้งหมดในสิ่งเดียวกัน

    หากคุณสนใจในรายละเอียดเพิ่มเติมเกี่ยวกับค่าใช้จ่ายในการเข้าสู่ระบบของการดำเนินงานเหล่านี้มาร์ตินมีคำอธิบายตรงไปตรงมาว่า


52

TRUNCATEจากนั้นการทดสอบDROPกับการทำDROPตรงนั้นแสดงให้เห็นว่าวิธีแรกจริง ๆ แล้วมีค่าใช้จ่ายในการบันทึกเพิ่มขึ้นเล็กน้อย

การดูข้อมูลบันทึกแต่ละรายการแสดงว่าTRUNCATE ... DROPเวอร์ชันเกือบจะเหมือนกันกับDROPเวอร์ชันยกเว้นมีรายการเพิ่มเติมเหล่านี้

+-----------------+---------------+-------------------------+
|    Operation    |    Context    |      AllocUnitName      |
+-----------------+---------------+-------------------------+
| LOP_COUNT_DELTA | LCX_CLUSTERED | sys.sysallocunits.clust |
| LOP_COUNT_DELTA | LCX_CLUSTERED | sys.sysrowsets.clust    |
| LOP_COUNT_DELTA | LCX_CLUSTERED | sys.sysrscols.clst      |
| LOP_COUNT_DELTA | LCX_CLUSTERED | sys.sysrscols.clst      |
| LOP_HOBT_DDL    | LCX_NULL      | NULL                    |
| LOP_MODIFY_ROW  | LCX_CLUSTERED | sys.sysallocunits.clust |
| LOP_HOBT_DDL    | LCX_NULL      | NULL                    |
| LOP_MODIFY_ROW  | LCX_CLUSTERED | sys.sysrowsets.clust    |
| LOP_LOCK_XACT   | LCX_NULL      | NULL                    |
+-----------------+---------------+-------------------------+

ดังนั้นTRUNCATEรุ่นแรกจึงเสียความพยายามเล็กน้อยในการอัพเดทบางอย่างในตารางระบบต่าง ๆ ดังนี้

  • อัปเดตrcmodifiedสำหรับคอลัมน์ตารางทั้งหมดในsys.sysrscols
  • อัปเดตrcrowsในsysrowsets
  • ศูนย์ออกpgfirst, pgroot, pgfirstiam, pcused, pcdata, pcreservedในsys.sysallocunits

แถวของตารางระบบเหล่านี้จะถูกลบเมื่อตารางถูกทิ้งในคำสั่งถัดไป

การทำลายเต็มรูปแบบของการบันทึกที่ดำเนินการโดยTRUNCATEvs DROPอยู่ด้านล่าง ฉันได้เพิ่มเข้ามาDELETEเพื่อการเปรียบเทียบ

+-------------------+-------------------+--------------------+------------------+-----------+---------------+-------------+------------------+-----------+---------------+-------------+
|                   |                   |                    |                            Bytes                           |                            Count                           |
+-------------------+-------------------+--------------------+------------------+-----------+---------------+-------------+------------------+-----------+---------------+-------------+
| Operation         | Context           | AllocUnitName      | Truncate / Drop  | Drop Only | Truncate Only | Delete Only | Truncate / Drop  | Drop Only | Truncate Only | Delete Only |
+-------------------+-------------------+--------------------+------------------+-----------+---------------+-------------+------------------+-----------+---------------+-------------+
| LOP_BEGIN_XACT    | LCX_NULL          |                    | 132              | 132       | 132           | 132         | 1                | 1         | 1             | 1           |
| LOP_COMMIT_XACT   | LCX_NULL          |                    | 52               | 52        | 52            | 52          | 1                | 1         | 1             | 1           |
| LOP_COUNT_DELTA   | LCX_CLUSTERED     | System Table       | 832              |           | 832           |             | 4                |           | 4             |             |
| LOP_DELETE_ROWS   | LCX_MARK_AS_GHOST | System Table       | 2864             | 2864      |               |             | 22               | 22        |               |             |
| LOP_DELETE_ROWS   | LCX_MARK_AS_GHOST | T                  |                  |           |               | 8108000     |                  |           |               | 1000        |
| LOP_HOBT_DDL      | LCX_NULL          |                    | 108              | 36        | 72            |             | 3                | 1         | 2             |             |
| LOP_LOCK_XACT     | LCX_NULL          |                    | 336              | 296       | 40            |             | 8                | 7         | 1             |             |
| LOP_MODIFY_HEADER | LCX_PFS           | Unknown Alloc Unit | 76               | 76        |               | 76          | 1                | 1         |               | 1           |
| LOP_MODIFY_ROW    | LCX_CLUSTERED     | System Table       | 644              | 348       | 296           |             | 5                | 3         | 2             |             |
| LOP_MODIFY_ROW    | LCX_IAM           | T                  | 800              | 800       | 800           |             | 8                | 8         | 8             |             |
| LOP_MODIFY_ROW    | LCX_PFS           | T                  | 11736            | 11736     | 11736         |             | 133              | 133       | 133           |             |
| LOP_MODIFY_ROW    | LCX_PFS           | Unknown Alloc Unit | 92               | 92        | 92            |             | 1                | 1         | 1             |             |
| LOP_SET_BITS      | LCX_GAM           | T                  | 9000             | 9000      | 9000          |             | 125              | 125       | 125           |             |
| LOP_SET_BITS      | LCX_IAM           | T                  | 9000             | 9000      | 9000          |             | 125              | 125       | 125           |             |
| LOP_SET_BITS      | LCX_PFS           | System Table       | 896              | 896       |               |             | 16               | 16        |               |             |
| LOP_SET_BITS      | LCX_PFS           | T                  |                  |           |               | 56000       |                  |           |               | 1000        |
| LOP_SET_BITS      | LCX_SGAM          | Unknown Alloc Unit | 168              | 224       | 168           |             | 3                | 4         | 3             |             |
+-------------------+-------------------+--------------------+------------------+-----------+---------------+-------------+------------------+-----------+---------------+-------------+
| Total             |                   |                    | 36736            | 35552     | 32220         | 8164260     | 456              | 448       | 406           | 2003        |
+-------------------+-------------------+--------------------+------------------+-----------+---------------+-------------+------------------+-----------+---------------+-------------+

การทดสอบดำเนินการในฐานข้อมูลที่มีรูปแบบการกู้คืนเต็มรูปแบบกับตาราง 1,000 แถวที่มีหนึ่งแถวต่อหน้า ตารางนี้ใช้ทั้งหมด 1,004 หน้าเนื่องจากหน้าดัชนีรูทและหน้าดัชนีระดับกลาง 3 หน้า

8 ของหน้าเหล่านี้คือการจัดสรรหน้าเดียวในขอบเขตผสมกับส่วนที่เหลือกระจายไปทั่ว 125 Uniform Extents การปันส่วน 8 หน้าเดียวแสดงขึ้นในLOP_MODIFY_ROW,LCX_IAMรายการบันทึก8 รายการ 125 deallocations LOP_SET_BITS LCX_GAM,LCX_IAMขอบเขตเป็น การดำเนินการทั้งสองนี้ยังต้องการการอัปเดตไปยังPFSหน้าเว็บที่เกี่ยวข้องด้วยดังนั้นจึงเป็นการรวม 133 LOP_MODIFY_ROW, LCX_PFSรายการ จากนั้นเมื่อตารางถูกลดลงข้อมูลเมตาเกี่ยวกับมันจำเป็นต้องถูกลบออกจากตารางระบบต่าง ๆ ดังนั้นLOP_DELETE_ROWSรายการบันทึกตาราง 22 ระบบ(คิดเป็นด้านล่าง)

+----------------------+--------------+-------------------+-------------------+
|        Object        | Rows Deleted | Number of Indexes | Delete Operations |
+----------------------+--------------+-------------------+-------------------+
| sys.sysallocunits    |            1 |                 2 |                 2 |
| sys.syscolpars       |            2 |                 2 |                 4 |
| sys.sysidxstats      |            1 |                 2 |                 2 |
| sys.sysiscols        |            1 |                 2 |                 2 |
| sys.sysobjvalues     |            1 |                 1 |                 1 |
| sys.sysrowsets       |            1 |                 1 |                 1 |
| sys.sysrscols        |            2 |                 1 |                 2 |
| sys.sysschobjs       |            2 |                 4 |                 8 |
+----------------------+--------------+-------------------+-------------------+
|                      |              |                   |                22 |
+----------------------+--------------+-------------------+-------------------+

สคริปต์แบบเต็มด้านล่าง

DECLARE @Results TABLE
(
    Testing int NOT NULL,
    Operation nvarchar(31) NOT NULL,
    Context nvarchar(31)  NULL,
    AllocUnitName nvarchar(1000) NULL,
    SumLen int NULL,
    Cnt int NULL
)

DECLARE @I INT = 1

WHILE @I <= 4
BEGIN
IF OBJECT_ID('T','U') IS NULL
     CREATE TABLE T(N INT PRIMARY KEY,Filler char(8000) NULL)

INSERT INTO T(N)
SELECT DISTINCT TOP 1000 number
FROM master..spt_values


CHECKPOINT

DECLARE @allocation_unit_id BIGINT

SELECT @allocation_unit_id = allocation_unit_id
FROM   sys.partitions AS p
       INNER JOIN sys.allocation_units AS a
         ON p.hobt_id = a.container_id
WHERE  p.object_id = object_id('T')  

DECLARE @LSN NVARCHAR(25)
DECLARE @LSN_HEX NVARCHAR(25)

SELECT @LSN = MAX([Current LSN])
FROM fn_dblog(null, null)


SELECT @LSN_HEX=
        CAST(CAST(CONVERT(varbinary,SUBSTRING(@LSN, 1, 8),2) AS INT) AS VARCHAR) + ':' +
        CAST(CAST(CONVERT(varbinary,SUBSTRING(@LSN, 10, 8),2) AS INT) AS VARCHAR) + ':' +
        CAST(CAST(CONVERT(varbinary,SUBSTRING(@LSN, 19, 4),2) AS INT) AS VARCHAR)

  BEGIN TRAN
    IF @I = 1
      BEGIN
          TRUNCATE TABLE T

          DROP TABLE T
      END
    ELSE
      IF @I = 2
        BEGIN
            DROP TABLE T
        END
      ELSE
        IF @I = 3
          BEGIN
              TRUNCATE TABLE T
          END  
      ELSE
        IF @I = 4
          BEGIN
              DELETE FROM T
          END                
  COMMIT

INSERT INTO @Results
SELECT @I,
       CASE
         WHEN GROUPING(Operation) = 1 THEN 'Total'
         ELSE Operation
       END,
       Context,
       CASE
         WHEN AllocUnitId = @allocation_unit_id THEN 'T'
         WHEN AllocUnitName LIKE 'sys.%' THEN 'System Table'
         ELSE AllocUnitName
       END,
       COALESCE(SUM([Log Record Length]), 0) AS [Size in Bytes],
       COUNT(*)                              AS Cnt
FROM   fn_dblog(@LSN_HEX, null) AS D
WHERE  [Current LSN] > @LSN  
GROUP BY GROUPING SETS((Operation, Context,
       CASE
         WHEN AllocUnitId = @allocation_unit_id THEN 'T'
         WHEN AllocUnitName LIKE 'sys.%' THEN 'System Table'
         ELSE AllocUnitName
       END),())


SET @I+=1
END 

SELECT Operation,
       Context,
       AllocUnitName,
       AVG(CASE WHEN Testing = 1 THEN SumLen END) AS [Truncate / Drop Bytes],
       AVG(CASE WHEN Testing = 2 THEN SumLen END) AS [Drop Bytes],
       AVG(CASE WHEN Testing = 3 THEN SumLen END) AS [Truncate Bytes],
       AVG(CASE WHEN Testing = 4 THEN SumLen END) AS [Delete Bytes],
       AVG(CASE WHEN Testing = 1 THEN Cnt END) AS [Truncate / Drop Count],
       AVG(CASE WHEN Testing = 2 THEN Cnt END) AS [Drop Count],
       AVG(CASE WHEN Testing = 3 THEN Cnt END) AS [Truncate Count],
       AVG(CASE WHEN Testing = 4 THEN Cnt END) AS [Delete Count]              
FROM   @Results
GROUP  BY Operation,
          Context,
          AllocUnitName   
ORDER BY Operation, Context,AllocUnitName        

DROP TABLE T

2

ตกลงคิดว่าฉันพยายามทำเกณฑ์มาตรฐานบางอย่างที่ไม่ต้องพึ่งพา "การแคชแบบอบอุ่น" เพื่อหวังว่าพวกเขาจะได้รับการทดสอบที่สมจริงยิ่งขึ้น (เช่นการใช้ Postgres เพื่อดูว่ามันตรงกับลักษณะเดียวกันของคำตอบที่โพสต์อื่น ๆ หรือไม่) :

มาตรฐานของฉันที่ใช้ postgres 9.3.4 พร้อมฐานข้อมูลขนาดใหญ่ (หวังว่าใหญ่พอที่จะไม่พอดีกับแคช RAM):

ใช้สคริปต์ฐานข้อมูลทดสอบนี้: https://gist.github.com/rdp/8af84fbb54a430df8fc0

กับ 10M แถว:

truncate: 1763ms
drop: 2091ms
truncate + drop: 1763ms (truncate) + 300ms (drop) (2063ms total)
drop + recreate: 2063ms (drop) + 242ms (recreate)

กับ 100M แถว:

truncate: 5516ms
truncate + drop: 5592ms
drop: 5680ms (basically, the exact same ballpark)

ดังนั้นจากนี้ฉันคาดเดาสิ่งต่อไปนี้: drop คือ "เกี่ยวกับ" เร็ว (หรือเร็วกว่า) เป็นตัด + drop (อย่างน้อยสำหรับ Postgres รุ่นทันสมัย) อย่างไรก็ตามถ้าคุณวางแผนที่จะหมุนและสร้างตารางใหม่คุณอาจ ยึดติดกับการตัดทอนตรงซึ่งเร็วกว่าการปล่อย + สร้างใหม่ (เข้าท่า) FWIW

หมายเหตุ 1: https://stackoverflow.com/questions/11419536/postgresql-truncation-speed/11423886#11423886 (กล่าวว่า postgres 9.2 อาจมีการตัดทอนเร็วกว่าเวอร์ชั่นก่อนหน้า) เช่นเคยเกณฑ์มาตรฐานกับระบบของคุณเองเพื่อดูลักษณะของมัน

หมายเหตุ 2: สามารถตัดทอนได้ใน postgres หากอยู่ในธุรกรรม: http://www.postgresql.org/docs/8.4/static/sql-truncate.html

หมายเหตุ 3: สามารถตัดทอนด้วยตารางขนาดเล็กบางครั้งช้ากว่าการลบ: https://stackoverflow.com/questions/11419536/postgresql-truncation-speed/11423886#11423886


1

กำลังเพิ่มมุมมองทางประวัติศาสตร์ ...

การดร็อปตารางต้องมีการอัพเดตหลายตารางระบบซึ่งโดยปกติแล้วจะต้องทำการเปลี่ยนแปลงตารางระบบเหล่านี้ในการทำรายการเดียว (คิดว่า "เริ่มต้น tran, ลบ syscolumns, ลบ sysobjects, commit")

นอกจากนี้ยังรวมอยู่ใน 'ตารางแบบเลื่อน' คือความจำเป็นในการจัดสรรคืนหน้าข้อมูล / ดัชนีทั้งหมดที่เกี่ยวข้องกับตาราง

หลายหลายหลายปีที่ผ่านมา ... กระบวนการยกเลิกการจัดสรรพื้นที่ถูกรวมอยู่ในธุรกรรมที่ปรับปรุงตารางระบบด้วยผลลัพธ์สุทธิคือจำนวนหน้าที่จัดสรรให้มากขึ้นยิ่งใช้เวลาในการยกเลิกการจัดสรรหน้าเว็บนานเท่าใด ทรานแซคชัน (บนตารางระบบ) ถูกเปิดทิ้งไว้และทำให้มีโอกาสมากขึ้นในการบล็อก (บนตารางระบบ) กระบวนการอื่น ๆ ที่พยายามสร้าง / วางตารางใน tempdb (โดยเฉพาะอย่างยิ่งน่ารังเกียจกับ allpages รุ่นเก่า == การล็อกระดับหน้าและศักยภาพสำหรับตาราง เพิ่มระดับล็อค)

วิธีแรกที่ใช้ (วิธีย้อนกลับ) เพื่อลดความขัดแย้งในตารางระบบคือการลดเวลาที่ล็อคถูกเก็บไว้ในตารางระบบและวิธีหนึ่งที่ค่อนข้างง่ายในการทำเช่นนี้คือการจัดสรรคืนหน้าข้อมูล / ดัชนีก่อนทิ้ง โต๊ะ.

ในขณะที่truncate tableไม่ได้ deallocate ทุกหน้าข้อมูล / ดัชนีก็ไม่ deallocate ทั้งหมด แต่หนึ่งใน 8 หน้า (ข้อมูล) ขอบเขต; 'แฮ็ค' อีกอันคือให้ดร็อปดัชนีทั้งหมดก่อนที่จะวางตาราง (ใช่แล้วแยก txn บน sysindexes แต่มีขนาดเล็กกว่า txn สำหรับ drop table)

เมื่อคุณพิจารณาว่า (อีกครั้งเมื่อหลายปีก่อน) มีเพียงฐานข้อมูลเดียว 'tempdb' และบางแอปพลิเคชันทำให้การใช้งานฐานข้อมูล 'tempdb' เดียวนั้นหนักมาก 'แฮ็ก' ใด ๆ ที่สามารถลดความขัดแย้งในตารางระบบใน 'tempdb' มีประโยชน์ เมื่อเวลาผ่านไปสิ่งต่าง ๆ ได้รับการปรับปรุง ... ฐานข้อมูลชั่วคราวหลายแห่งการล็อกระดับแถวบนตารางระบบวิธีการจัดสรรคืนที่ดีกว่า ฯลฯ

ในระหว่างนี้การใช้งานtruncate tableจะไม่ทำร้ายอะไรเลยหากทิ้งไว้ในรหัส


-2

มันเหมาะสมที่จะทำ TRUNCATE สำหรับตารางที่มีคีย์ต่างประเทศ อย่างไรก็ตามสำหรับตารางชั่วคราวเพียง DROP ก็เพียงพอแล้ว


TRUNCATE จะหลีกเลี่ยงความขัดแย้งที่สำคัญกับต่างประเทศอย่างไร อย่างไร?
user259412

1
จะเขียนข้อผิดพลาดว่ามีคีย์ต่างประเทศ
Evgeniy Gribkov

-8

ประเด็นสำคัญtruncateคือการลบทุกอย่างในตารางอย่างง่ายดายและไม่สามารถเพิกถอนได้ (ข้อมูลจำเพาะทางเทคนิคบางอย่างที่อ้างอิงจากเอนจิ้นการจัดเก็บข้อมูลอาจแตกต่างกันเล็กน้อย) - การข้ามการบันทึกหนัก ฯลฯ

drop tableบันทึกการเปลี่ยนแปลงทั้งหมดเมื่อมีการเปลี่ยนแปลง ดังนั้นเพื่อให้มีการเข้าสู่ระบบน้อยที่สุดและลดการปั่นระบบที่ไร้ประโยชน์ฉันคิดว่าตารางที่มีขนาดใหญ่มากอาจถูกตัดทอนก่อนจากนั้นจึงลดลง

truncate อาจถูกห่อในธุรกรรม (ซึ่งจะเป็นตัวเลือกที่ปลอดภัยที่สุด) ซึ่งแน่นอนว่าจะช่วยให้คุณย้อนกลับการดำเนินการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.