У нас есть приложение для отслеживания в реальном времени, в которое мы вставляем точку отслеживания в одну таблицу с именем Tracking
.У нас есть еще одна таблица с именем ExistingAddressPointTable
, где у нас есть адрес доставки.Мы рассматриваем конкретный адрес как доставленный, когда доставщик находится в радиусе 200 метров от этого адреса, и вставляем запись доставки в непространственную таблицу, называемую таблицей Delivery
(отношения многие ко многим).
Мы создаем APIзвоните через 20-30 секунд каждой минуты, следовательно, устройство всегда отправляет 10-15 адресных точек в этот период.Я реализую решение для этого в хранимой процедуре, но проблема заключается даже в том, что сеанс одновременной доставки 20 человек в Azure SQL Server достигает 100%.Я хочу поддерживать эту систему для 1000 одновременных сеансов.
Мы используем базу данных Azure SQL Server в эластичном пуле, имеющем ограничение 50 DTU в среде UAT.У нашего клиента уже есть 5 других БД по 250 ГБ каждый в том же эластичном пуле.Для производства также у нас есть ограничение в 100 DTU.
Любое решение для достижения Delivery
Мальчик отслеживает через разные мобильные устройства?
Используемая технология: ядро .net, Web API и Azure SQL Server 2017, пространственная индексация в пространственной таблице (Tracking
& ExistingAddressPointTable
) уже применяется.Любая помощь очень ценится.
PSB код для справки
CREATE Procedure [dbo].[InsertTrackingPoint]
@points AddressPointType READONLY,
@name NVARCHAR(150),
@isDisConnected BIT,
@jobId BIGINT -- with current scenario of implementation.This is not required
AS
BEGIN
Declare @routeId bigint;
Declare @point nvarchar(700);
DECLARE @totalRecords INT
DECLARE @I INT
DECLARE @trackingId bigint
Declare @deliveryBoyId bigint;
DECLARE @route As TABLE(Id int Identity,RouteId bigint,JobId bigint);
Select Top 1 @deliveryBoyId=Id from DeliveryPerson with(Nolock) where --Take DeliveryPerson Id FROM DeliveryPerson Table to insert breadcrumb against particular Id
(DeliveryPerson.Name LIKE @name) OR ( DeliveryPerson.Email LIKE @name ) AND IsActive=1
Insert into @route
Select Id As RouteId,JobId from Route With(Nolock) where CarrierID=@deliveryBoyId AND JobId in( Select Id From Job where EndDate>=Convert(date,GETDATE())AND IsActive=1)
AND TotalAddressPoint>0
order by Id desc --Inserting all the active jobs assigned to that carrier and also checking if addresspoint count is greater than 0.It means we are taking those Jobs whose addressPoint count is greater than 0.
Declare @J INT;
DECLARE @totalRouteCount INT;
SET @J=1;--Iterator variable
SELECT @totalRecords = COUNT(Point) FROM @points--taking count of all the addresspoints coming from Mobile device.
print @totalRecords
print @totalRouteCount
SELECT @totalRouteCount=Count(*) FROM @route --taking count of all the active Jobs/Routes of Jobs assigned to carrier
print @totalRouteCount
DECLARE @addressPoint geography;
DECLARE @speed bigint;
DECLARE @direction nvarchar(100);
DECLARE @capturedFrom nvarchar(100);
DECLARE @accuracy decimal;
DECLARE @isDisconnectedPoint bit
SET @I=1;
WHILE (@I <= @totalRecords)
BEGIN
Select @addressPoint=GEOGRAPHY::STGeomFromText (points.Point,4326),@speed=points.Speed,@direction=points.Direction,
@capturedFrom=points.CapturedFrom,@accuracy=points.Accuracy ,
@isDisconnectedPoint= points.IsDisconnect,@accuracy=points.Accuracy from @points points where points.Id=@I
Insert into Tracking(CarrierId,Point,Speed,Direction,CapturedFrom,CapturedAt,Accuracy,IsDisconnect,CreatedOn,IsActive) --inserting mobile addresspoint to Tracking table.
Values(@deliveryBoyId,
@addressPoint,
(@speed*2.237)
,@direction,
@capturedFrom ,
CONVERT(VARCHAR(23), (Select points.CapturedAt from @points points where points.Id=@I), 121),
@accuracy,
@isDisconnectedPoint
,GETDATE()
,1
)
SELECT TOP 1 @trackingId=Id from Tracking order by Id desc
if(@totalRouteCount>0)
BEGIN
SET @j=1;
Insert into Delivery(AddressPointId,TrackingId,RouteId,JobId,CreatedOn,IsActive)
Select (address.Id),@trackingId,rJob.RouteId,rJob.JobId,GetDate(),1
FROM ExistingAddressPointTable address JOIN @route rJob ON rJob.RouteId=address.RouteJobID
where address.point.STDistance(@addressPoint)<200
AND address.IsDelivered=0--Non spatial table but still this is 2nd highest CPU usage query.Frankly speaking,I dont know why.
update addres
set addres.IsDelivered =1
from ExistingAddressPointTable addres inner join @routeJob rout on addres.RouteId = rout.RouteId
where addres.point.STDistance(@addressPoint)<200 --Table have 15 millions record now.In azure server this query takes huge CPU spike
AND addres.IsDelivered=0
END
SET @I=@I+1;
END
IF(@isDisConnected=1)--Updating delivery boy status to deactivate mode to his last tracking record.
BEGIN
Select TOP 1 @trackingId=Id from Tracking where DeliveryBoyId=@deliveryBoyId AND IsActive=1 Order by Id desc
Update Tracking set IsDisconnect=1 where Id=@trackingId
END
END