Ho molti dati. Oggetti con altri oggetti nidificati come questo (JSON):
{
id: 12,
Code: "a code",
country: "at",
prices:
[{
{ price: 100, from "2017-05-05", to "2017-06-05" },
{ price: 150, from "2017-05-06", to "2017-06-06" },
{ price: 200, from "2017-05-07", to "2017-06-07" },
}]
}
ecc. Ho circa 60k di questi oggetti principale / genitore. I prezzi sono circa 3 milioni di oggetti.
Situazione attuale
Ho creato un DB SQL di Azure relazionale con tabelle per gli oggetti e una tabella di prezzi con chiave esterna. Lo stesso vale per la tabella dei paesi, ecc. Non ho problemi con i database relazionali. Ho avuto un'istanza S3 di un database SQL di Azure e anche un LocalDB. Entrambi sono non abbastanza veloci . Per inserire o aggiornare, utilizzo la stored procedure. Uno per tavolo. Quindi per archiviare solo 1 oggetto, eseguo un proc memorizzato per scoprirlo, necessita di un inserto o di un aggiornamento e immagazzino l'oggetto principale / principale. Restituisce il (nuovo) ID e lo imposta come chiave esterna per l'oggetto prezzo. Inoltre, memorizza circa 100 oggetti di prezzo e passa a quello successivo. Questo richiede più di un'ora per memorizzare 100 oggetti principale / principale con i relativi prezzi.
Le soluzioni che considero
- upscale ad Azure SQL Premium e ridimensiona a S0 (standard) quando ho finito. docs
- vai in memoria (che non ha chiavi esterne ...)
- passa a NoSQL (cosmos db)
Ho provato la soluzione 3 e ho trovato questo:
Ho fatto una dimostrazione del concetto memorizzando gli oggetti come json in cosmos db (era ancora un documento db allora) ed era veloce. Tuttavia, l'esecuzione di query è stato difficile perché non è possibile eseguire una sottoquery o una media o una somma. link
o dovrei memorizzare le righe dei prezzi come nuovi documenti e avere una "chiave esterna" sull'oggetto principale / principale?
Devo scavare di più nell'opzione 3, o consiglieresti 1 o 2?
Modifica per Ewan I miei stored proc: per oggetto principale / principale:
ALTER PROCEDURE [dbo].[InsertUpdateParent]
(
@code nvarchar(max),
@name nvarchar(max),
@lat float,
@lng float,
@country int,
@countryCode nvarchar(2)
)
AS
BEGIN
DECLARE @id int;
DECLARE @err int;
DECLARE @newObject bit;
SET NOCOUNT ON
IF (@country = 0)
begin
select @country = id from countries where code = @countrycode;
SELECT @err = @@error;
end
IF EXISTS (SELECT ID FROM ParentObject where code = @code)
begin
SELECT @id = ID FROM ParentObject where code = @code;
SELECT @err = @@error;
SELECT @newObject = 0;
UPDATE ParentObject SET
[Name] = @name,
Latitude = @lat,
Longitude = @lng,
CountryId = @country
WHERE code = @code;
SELECT @err = @@error;
end
else
begin
SELECT @newObject = 1;
INSERT INTO [dbo].[ParentObject]
([Code]
,[Name]
,[Latitude]
,[Longitude]
,[CountryId]
VALUES
(@code, @name, @lat, @lng, @country);
select @id = SCOPE_IDENTITY();
SELECT @err = @@error;
end
IF @err <> 0
PRINT '@err is ' + ltrim(str(@err)) + '.'
else
return @id;
END
e per i prezzi:
ALTER PROCEDURE [dbo].[InsertUpdatePrices]
(
@from as datetime,
@to as datetime,
@parentId as int,
@price as decimal(18,2)
)
AS
BEGIN
declare @id int;
SET NOCOUNT ON
IF EXISTS (SELECT ID FROM prices where ArrivalDateFrom = @from and ArrivalDateTo= @to and ParentObjectId = @parentId )
begin
SELECT @id = ID FROM prices where ArrivalDateFrom = @from and ArrivalDateTo= @to and ParentObjectId = @parentId;
UPDATE [dbo].[Prices]
SET
[ArrivalDateFrom] = @from,
[ArrivalDateTo] = @to,
[Price] = @price,
[ParentObjectId] = @parentId
WHERE ID = @id
end
else
begin
INSERT INTO [dbo].[Prices]
([ArrivalDateFrom]
,[ArrivalDateTo]
,[Price]
,[ParentObjectId])
VALUES
(@from
,@to
,@price
,@parentId);
select @id = SCOPE_IDENTITY();
end
return @id;
END