Aracılığıyla paylaş


Bellek içi OLTP ile JSON işlemeyi iyileştirme

Şunlar için geçerlidir: SQL Server 2017 (14.x) ve sonraki sürümleri Azure SQL Veritabanı,Azure SQL Yönetilen Örneği,ve Microsoft Fabric'teki SQL veritabanı

SQL Server ve Azure SQL Veritabanı, JSON olarak biçimlendirilmiş metinlerle çalışmanıza olanak sağlar. JSON verilerini işleyen sorguların performansını artırmak için standart dize sütunlarını (nvarchar türü) kullanarak JSON belgelerini bellek için iyileştirilmiş tablolarda depolayabilirsiniz. JSON verilerini bellek için iyileştirilmiş tablolarda depolamak, kilitsiz, bellek içi veri erişimi kullanarak sorgu performansını artırır.

JSON'i bellek için iyileştirilmiş tablolarda depolama

Aşağıdaki örnekte, Product ve Tagsolmak üzere iki JSON sütunu içeren bellek için iyileştirilmiş bir Data tablosu gösterilmektedir:

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

Ek bellek içi özelliklerle JSON işlemeyi iyileştirme

JSON işlevselliğini mevcut bellek içi OLTP teknolojileriyle tamamen tümleştirebilirsiniz. Örneğin, aşağıdakileri yapabilirsiniz:

JSON sütunlarını doğrulama

Bellek için iyileştirilmiş tablolarınızda depolanan JSON metninin düzgün biçimlendirildiğinden emin olmak için dize sütununda depolanan JSON belgelerinin içeriğini doğrulayan yerel olarak derlenmiş CHECK kısıtlamaları ekleyebilirsiniz.

Aşağıdaki örnek, ProductJSON sütununa sahip bir Tags tablosu oluşturur. Tags sütununda, sütundaki JSON metnini doğrulamak için ISJSON işlevini kullanan bir CHECK kısıtlaması vardır.

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

Yerel olarak derlenmiş CHECK kısıtlamasını JSON sütunları içeren mevcut bir tabloya da ekleyebilirsiniz.

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

Hesaplanan sütunları kullanarak JSON değerlerini kullanıma sunma

Hesaplanan sütunlar, JSON metnindeki değerleri kullanıma sunmanıza ve JSON metnindeki değeri yeniden getirmeden ve JSON yapısını yeniden ayrıştırmadan bu değerlere erişmenize olanak sağlar. Bu şekilde kullanıma sunulan değerler, hesaplanan sütunlarda kesin olarak türlenir ve fiziksel olarak kalıcı olur. Kalıcı hesaplanan sütunlar kullanarak JSON değerlerine erişmek, JSON belgesindeki değerlere doğrudan erişmekten daha hızlıdır.

Aşağıdaki örnek, JSON Data sütunundan iki değerin nasıl açığa çıkarılacağını gösteriyor.

  • Ürünün yapıldığı ülke/bölge.
  • Ürün üretim maliyeti.

Bu örnekte, MadeIn sütununda depolanan JSON belgesi her değiştiğinde hesaplanan sütunlar Cost ve Data güncelleştirilir.

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

JSON sütunlarındaki dizin değerleri

Bellek için iyileştirilmiş dizinleri kullanarak JSON sütunlarındaki değerleri dizinleyebilirsiniz. Dizine alınan JSON değerleri, önceki örnekte açıklandığı gibi hesaplanan sütunlar kullanılarak kullanıma sunulmalı ve güçlü şekilde yazılmalıdır.

JSON sütunlarındaki değerler hem standart NONCLUSTERED hem de HASH dizinleri kullanılarak dizinlenebilir.

  • KÜMELENMİYEN dizinler, satır aralıklarını bazı JSON değerlerine göre seçen veya sonuçları JSON değerlerine göre sıralayan sorguları iyileştirir.
  • KARMA dizinleri, bulmak için tam bir değer belirterek tek bir satır veya birkaç satır seçen sorguları iyileştirir.

Aşağıdaki örnek, iki hesaplanan sütun kullanarak JSON değerlerini kullanıma sunan bir tablo oluşturur. Örnek, bir JSON değeri için KÜMELENMEMİŞ bir dizin, diğeri için ise bir KARMA dizini oluşturur.

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 sorgularının yerel derlemesi

Yordamlarınız, işlevleriniz ve tetikleyicileriniz yerleşik JSON işlevlerini kullanan sorgular içeriyorsa, yerel derleme bu sorguların performansını artırır ve bunları çalıştırmak için gereken CPU döngülerini azaltır.

Aşağıdaki örnekte, çeşitli JSON işlevleri kullanan yerel olarak derlenmiş bir yordam gösterilmektedir: JSON_VALUE, OPENJSONve 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

Yerleşik JSON desteğine görsel bir giriş için aşağıdaki videolara bakın:

  • NoSQL ile ilişkisel dünyalar arasında bir köprü olarak JSON