Tag Archive optimize

Byphunsanit

MSSQL: optimize (audit) bit

สาเหตุที่เขียนว่า audit bit เพราะว่าตอนแรกตั้งใจจะเขียน script optimize มา alter column แต่มันไม่มีอะไรให้ปรับแต่งได้แล้ว นอกจากเอา column ออกเลยการเป็น audit script ไปแทน

Data Type BIT ไม่สามารถ (และไม่จำเป็นต้อง) ปรับแก้ขนาดด้วยคำสั่ง ALTER ด้วยเหตุผลทางเทคนิค

  1. มันเก็บแค่ 0 กับ 1 ไม่มีอะไรจะเล็กไปกว่านี้แล้ว นอกจากจะ ลบ column ทิ้ง ไม่เก็บมันไปเลย
  2. SQL Server จัดการให้เอง (Auto Packing): มีกลไกภายในที่จะกวาดคอลัมน์ BIT ทั้งหมดในตาราง (ไม่ว่าจะอยู่ตรงไหน) มารวมมัดเป็นก้อน (Byte) เดียวกันให้อัตโนมัติ

alter_table_optimize_by_storage_bytes_columns_types_bit.sql

/*
Reference Storage Size:
1. BIT:
   https://learn.microsoft.com/en-us/sql/t-sql/data-types/bit-transact-sql?view=sql-server-ver16#storage
   - The SQL Server Database Engine optimizes storage of bit columns.
   - If there are 8 or fewer bit columns in a table, the columns are stored as 1 byte.
   - If there are from 9 up to 16 bit columns, they are stored as 2 bytes, and so on.
   (Formula: CEILING(TotalBits / 8) Bytes)
*/

WITH BitColumnStats AS (
    SELECT
        table_catalog,
        table_schema,
        table_name,
        COUNT(*) AS TotalBitColumns
    FROM
        information_schema.columns
    WHERE
        DATA_TYPE = 'bit'
        AND table_schema NOT IN ('sys', 'information_schema')
    GROUP BY
        table_catalog, table_schema, table_name
)
SELECT
    table_catalog AS DatabaseName,
    table_schema AS SchemaName,
    table_name AS TableName,
    TotalBitColumns,

    -- คำนวณจำนวน Bytes ที่ใช้จริงสำหรับกลุ่ม BIT นี้
    -- สูตร: ปัดเศษขึ้นของ (จำนวนคอลัมน์ / 8)
    CEILING(TotalBitColumns / 8.0) AS StorageBytesUsed,

    -- คำนวณว่าเหลือที่ว่างอีกกี่ Bit ใน Byte ก้อนปัจจุบัน
    (CAST(CEILING(TotalBitColumns / 8.0) AS INT) * 8) - TotalBitColumns AS FreeBitsAvailable,

    -- วิเคราะห์และให้คำแนะนำ
    CASE
        WHEN (CAST(CEILING(TotalBitColumns / 8.0) AS INT) * 8) - TotalBitColumns = 0 THEN
            'Full Packing: Efficiently used. (Next BIT column will cost +1 Byte)'
        ELSE
            'Free Capacity: Can add ' +
            CAST((CAST(CEILING(TotalBitColumns / 8.0) AS INT) * 8) - TotalBitColumns AS VARCHAR) +
            ' more BIT column(s) without increasing row size.'
    END AS EfficiencyInsight

FROM
    BitColumnStats
ORDER BY
    DatabaseName,  -- เรียงตาม Database
    SchemaName,    -- เรียงตาม Schema
    TableName;     -- เรียงตาม Table (ไม่มี ColumnName เพราะเป็นการนับรวมทั้งตาราง)

อ่านเพิ่มเติม