Megosztás a következőn keresztül:


JSON-feldolgozás optimalizálása memóriabeli OLTP-vel

A következőkre vonatkozik: Az SQL Server 2017 (14.x) és újabb verziói az Azure SQL DatabaseAzure SQL Managed InstanceSQL Database-adatbázist a Microsoft Fabricben

Az SQL Server és az Azure SQL Database segítségével JSON-ként formázott szövegekkel dolgozhat. A JSON-adatokat feldolgozó lekérdezések teljesítményének növelése érdekében jSON-dokumentumokat tárolhat memóriaoptimalizált táblákban standard sztringoszlopokkal (nvarchar típus). A JSON-adatok memóriaoptimalizált táblákban való tárolása zárolásmentes, memóriabeli adathozzáférés használatával növeli a lekérdezési teljesítményt.

JSON tárolása memóriaoptimalizált táblákban

Az alábbi példa egy memóriaoptimalizált Product táblázatot mutat be, amely két JSON-oszlopot tartalmaz, Tags és Data:

CREATE SCHEMA xtp;
GO

CREATE TABLE xtp.Product (
    ProductID INT PRIMARY KEY NONCLUSTERED, --standard column
    Name NVARCHAR(400) NOT NULL, --standard column
    Price FLOAT, --standard column
    Tags NVARCHAR(400), --JSON stored in string column
    Data NVARCHAR(4000) --JSON stored in string column
)
WITH (MEMORY_OPTIMIZED = ON);
GO

JSON-feldolgozás optimalizálása további memóriabeli funkciókkal

A JSON-funkciók teljes mértékben integrálhatók a meglévő memóriabeli OLTP-technológiákkal. Például a következő műveleteket hajthatja végre:

JSON-oszlopok ellenőrzése

A sztringoszlopban tárolt JSON-dokumentumok tartalmának ellenőrzéséhez natívan lefordított CHECK-korlátozásokat adhat hozzá, hogy a memóriaoptimalizált táblákban tárolt JSON-szöveg megfelelően legyen formázva.

Az alábbi példa létrehoz egy Product táblát egy JSON típusú oszloppal Tags. A Tags oszlopban van egy CHECK korlátozás, amely a ISJSON függvénnyel ellenőrzi az oszlop JSON-szövegét.

DROP TABLE IF EXISTS xtp.Product;
GO
CREATE TABLE xtp.Product (
    ProductID INT PRIMARY KEY NONCLUSTERED,
    Name NVARCHAR(400) NOT NULL,
    Price FLOAT,
    Tags NVARCHAR(400)
        CONSTRAINT [Tags should be formatted as JSON] CHECK (ISJSON(Tags) = 1),
    Data NVARCHAR(4000)
)
WITH (MEMORY_OPTIMIZED = ON);
GO

A natívan lefordított CHECK korlátozást egy meglévő táblához is hozzáadhatja, amely JSON-oszlopokat tartalmaz.

ALTER TABLE xtp.Product
    ADD CONSTRAINT [Data should be JSON]
        CHECK (ISJSON(Data)=1);

JSON-értékek megtekintése számított oszlopok révén

A számított oszlopok lehetővé teszik az értékek JSON-szövegből való felfedését, és az értékek elérését anélkül, hogy újra beolvassa az értéket a JSON-szövegből, és nem elemezheti újra a JSON-struktúrát. Az így közzétett értékek szigorúan típushoz kötöttek, és fizikailag vannak tárolva a számított oszlopokban. A JSON-értékek elérése a megőrzött számított oszlopok használatával gyorsabb, mint a JSON-dokumentum értékeinek elérése közvetlenül.

Az alábbi példa bemutatja, hogyan teheti közzé a következő két értéket a JSON Data oszlopból:

  • Az az ország/régió, ahol a terméket készítik.
  • A termék gyártási költsége.

Ebben a példában a számított oszlopok MadeIn és Cost minden alkalommal frissülnek, amikor a Data oszlopban tárolt JSON-dokumentum megváltozik.

DROP TABLE IF EXISTS xtp.Product;
GO
CREATE TABLE xtp.Product (
    ProductID INT PRIMARY KEY NONCLUSTERED,
    Name NVARCHAR(400) NOT NULL,
    Price FLOAT,
    Data NVARCHAR(4000),
    MadeIn AS CAST(JSON_VALUE(Data, '$.MadeIn') AS NVARCHAR(50)) PERSISTED,
    Cost AS CAST(JSON_VALUE(Data, '$.ManufacturingCost') AS FLOAT) PERSISTED
)
WITH (MEMORY_OPTIMIZED = ON);
GO

Indexértékek JSON-oszlopokban

A JSON-oszlopok értékeit memóriaoptimalizált indexekkel indexelheti. Az indexelt JSON-értékeket ki kell fedni és szigorúan be kell gépelni számított oszlopok használatával, az előző példában leírtak szerint.

A JSON-oszlopok értékei a standard NEMCLUSTERED és a HASH indexek használatával is indexelhetők.

  • A NEMCLUSTERED indexek olyan lekérdezéseket optimalizálnak, amelyek sortartományokat választanak ki valamilyen JSON-érték alapján, vagy JSON-értékek szerint rendezik az eredményeket.
  • HASH-indexek optimalizálják azokat a lekérdezéseket, amelyek pontos értéket keresnek, például egyetlen sort vagy néhány sort választanak ki.

Az alábbi példa egy olyan táblát hoz létre, amely két számított oszlop használatával teszi elérhetővé a JSON-értékeket. A példa létrehoz egy NEMCLUSTERED indexet az egyik JSON-értéken, a másikon pedig egy HASH-indexet.

DROP TABLE IF EXISTS xtp.Product;
GO
CREATE TABLE xtp.Product (
    ProductID INT PRIMARY KEY NONCLUSTERED,
    Name NVARCHAR(400) NOT NULL,
    Price FLOAT,
    Data NVARCHAR(4000),
    MadeIn AS CAST(JSON_VALUE(Data, '$.MadeIn') AS NVARCHAR(50)) PERSISTED,
    Cost AS CAST(JSON_VALUE(Data, '$.ManufacturingCost') AS FLOAT) PERSISTED,
    INDEX [idx_Product_MadeIn] NONCLUSTERED (MadeIn)
)
WITH (MEMORY_OPTIMIZED = ON);
GO

ALTER TABLE Product ADD INDEX [idx_Product_Cost] NONCLUSTERED HASH (Cost)
    WITH (BUCKET_COUNT = 20000);

JSON-lekérdezések natív fordítása

Ha az eljárások, függvények és eseményindítók olyan lekérdezéseket tartalmaznak, amelyek a beépített JSON-függvényeket használják, a natív fordítás növeli ezeknek a lekérdezéseknek a teljesítményét, és csökkenti a futtatáshoz szükséges processzorciklusokat.

Az alábbi példa egy natívan lefordított eljárást mutat be, amely több JSON-függvényt használ: JSON_VALUE, OPENJSONés JSON_MODIFY.

CREATE PROCEDURE xtp.ProductList (@ProductIds NVARCHAR(100))
WITH SCHEMABINDING, NATIVE_COMPILATION
AS BEGIN
    ATOMIC WITH (TRANSACTION ISOLATION LEVEL = snapshot, LANGUAGE = N'English')

    SELECT ProductID,
        Name,
        Price,
        Data,
        Tags,
        JSON_VALUE(data, '$.MadeIn') AS MadeIn
    FROM xtp.Product
    INNER JOIN OPENJSON(@ProductIds)
        ON ProductID = value
END;
GO

CREATE PROCEDURE xtp.UpdateProductData (
    @ProductId INT,
    @Property NVARCHAR(100),
    @Value NVARCHAR(100)
)
WITH SCHEMABINDING, NATIVE_COMPILATION
AS BEGIN
    ATOMIC WITH (TRANSACTION ISOLATION LEVEL = snapshot, LANGUAGE = N'English')

    UPDATE xtp.Product
    SET Data = JSON_MODIFY(Data, @Property, @Value)
    WHERE ProductID = @ProductId;
END
GO

A beépített JSON-támogatás vizuális bemutatásához tekintse meg az alábbi videókat: