I have a table with around 8 million rows with a schema of:
CREATE TABLE [dbo].[Documents](
[Id] [uniqueidentifier] NOT NULL,
[RemoteId] [int] NOT NULL,
[Json] [nvarchar](max) NULL,
[WasSuccessful] [bit] NOT NULL,
[StatusCode] [int] NULL,
[Created] [datetime2](7) NULL,
CONSTRAINT [PK_Documents] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[Documents] ADD CONSTRAINT [DF_Documents_Id] DEFAULT (newsequentialid()) FOR [Id]
GO
ALTER TABLE [dbo].[Documents] ADD CONSTRAINT [DF_Documents_Created] DEFAULT (getdate()) FOR [Created]
GO
The json documents are of a structure of
{
"Id": 1,
"Data": [
{
"Id": 99,
"Name": "Person 1"
},
{
"Id": 100,
"Name": "Person 2"
}
]
}
I am attempting to extract the JSON array from within the document and insert it into a new table using the following query:
;WITH CTE (Json) AS
(
SELECT TOP 10
JSON_QUERY([Json], '$.Data')
FROM
Documents
WHERE
ISJSON([Json]) > 0
)
INSERT INTO [dbo].[ParsedDocuments] (Id, Name)
SELECT
JSON_VALUE([Value], '$.Id') AS [Id],
JSON_VALUE([Value], '$.Name') AS [Name],
FROM
CTE
CROSS APPLY
OPENJSON([Json]) as X
What I'm finding is that if I extract and query a sample of the data, say 1000 rows. Everything works as expected and the data is inserted into the destination table. However, when I query the main table the server appears to just hang and become unresponsive.
I suspect that it is attempting to run a cross apply across all the rows before inserting data. Is there any way to improve performance? Or allow the job to begin "streaming" results into the destination table rather than attempting to batch them up?
Finally, as you can see I am employing the use of "TOP 10" results. I am however still experiencing the performance hanging. And I am unsure as to why.
Query plans for large table are never generated how when running against a sample of the data the query plan can be found here.