У политики есть набор insuranceTypes
в PolicyCoverage
.
У политики есть набор insuranceTypes
для конкретной организации в PolicyPermissionInsuranceType
.
Я пытаюсь получить полисы, которые имеют все формы страхования PolicyCoverage
в PolicyPermissionInsuranceType
для конкретной организации, пользователя и разрешения.
В C # я оцениваю правило (для отдельной политики, если оно найдено для организации) как:
public class ReadPolicyLimitedPermission
{
private IEnumerable<Guid> InsuranceTypeIds { get; }
public bool Validate(Policy entity)
{
return !entity.InsuranceTypes.Except(InsuranceTypeIds).Any();
}
}
Я пытаюсь написать запрос, равный этому правилу, для всех политик в базе данных. У меня такой запрос выглядит следующим образом, но он очень медленный, когда поставляется с userId
, для которого нет записи в таблице.
Итак, вопрос в том, есть ли лучший способ выполнить этот тип проверки?
Запрос:
declare @UserId uniqueidentifier = newId() --Does not exist
declare @Permission nvarchar(150) = 'ReadPolicyLimitedPermission'
select p.Id
from test.Policy p
where
not exists
(
select
pc.insuranceTypeId
from
test.PolicyCoverage pc
where
pc.PolicyId = p.Id
except
select
ppit.InsuranceType
from
test.PolicyPermissionInsuranceType ppit
where
ppit.UserId = @UserId and
ppit.Permission = @Permission and
ppit.OrganizationId = p.OrganizationId
)
Размеры стола:
Policy 201762 rows
PolicyCoverage 393004 rows
PolicyPermissionInsuranceType 36984 rows
План выполнения:
![enter image description here](https://i.stack.imgur.com/VFHSA.png)
Структура таблицы:
CREATE TABLE [test].[Policy](
[Id] [uniqueidentifier] NOT NULL,
[OrganizationId] [uniqueidentifier] NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [test].[PolicyCoverage](
[PolicyId] [uniqueidentifier] NOT NULL,
[InsuranceTypeId] [uniqueidentifier] NOT NULL
) ON [PRIMARY]
CREATE TABLE [test].[PolicyPermissionInsuranceType](
[UserId] [uniqueidentifier] NOT NULL,
[OrganizationId] [uniqueidentifier] NOT NULL,
[Permission] [nvarchar](50) NOT NULL,
[InsuranceType] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_PolicyPermissionInsuranceType] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[OrganizationId] ASC,
[Permission] ASC,
[InsuranceType] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Или можно хранить данные по-другому для таблицы PolicyPermissionInsuranceType
Пример:
Policy 1
-Org 1
-Type 1
-Type 2
Policy 2
-Org 1
-Type 1
-Type 3
PolicyPermission 1
-Org1
-Type1
-Type2
-Type5
Запрос им должен возвращать Policy1, так как он имеет все типы в таблице policyPermission (Type1, Type2), но не Policy2, так как у него есть Type3, которого у PolicyPermission1 нет.