策略在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
表结构:
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,而Policy3没有。
答案 0 :(得分:1)
如果尝试此操作怎么办:
select a.id from (
select p.id,ppt.userid From test.Policy p
join test.PolicyCoverage pc on pc.policyid = p.id
left join test.PolicyPermissionInsuranceType ppt on ppt.InsuranceType = pc.insurancetypeid
and ppt.OrganizationId = p.OrganizationId
and ppt.UserId = @UserId
and ppt.Permission = @Permission
)a
group by a.id
having COUNT(a.id) = COUNT(a.userid)
答案 1 :(得分:0)
我将其发布为答案,因为我想添加一些可以测试的代码,因此似乎不适合注释。除非您觉得有用,否则会很乐意删除。
您可能希望预先在子查询中创建第二个表作为临时表,然后在子查询中引用该表,这可能会加快速度:
declare @UserId uniqueidentifier = newId() --Does not exist
declare @Permission nvarchar(150) = 'ReadPolicyLimitedPermission'
-- temp table here
select ppit.InsuranceType, ppit.OrganizationId
into #temp
from test.PolicyPermissionInsuranceType ppit
where ppit.UserId = @UserId and
ppit.Permission = @Permission
-- original modified query with temp table
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 #temp ppit
where ppit.OrganizationId = p.OrganizationId
)