【发布时间】:2014-02-05 10:52:45
【问题描述】:
好的,所以我需要找出在我的数据库中执行一些动态构建查询的最佳方法。
我有两张桌子MA_Objects 和MA_Attributes。 MA_Objects 包含用户列表,并具有表示与该用户相关的单值属性的列。 (例如,名字、姓氏)。 MA_Attributes 包含该用户的多值属性(例如电子邮件地址)。
MA_Attributes 存储由强制属性名称和属性值列组成的值对,这取决于其数据类型。所以每一列都会有一个attributeName,如果该属性是一个字符串,那么它的值将在attributeValueString中。其他 attributeValue* 列必须为 null。
表结构如下
CREATE TABLE [dbo].[MA_Objects](
[id] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[firstName] [nvarchar](400) NULL,
[givenNames] [nvarchar](400) NULL,
[middleName] [nvarchar](400) NULL,
[surname] [nvarchar](400) NULL,
[objectclass] [nvarchar](400) NULL,
[supervisor] [uniqueidentifier] NULL
CREATE TABLE [dbo].[MA_Attributes](
[id] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[objectId] [uniqueidentifier] NOT NULL,
[attributeName] [nvarchar](30) NOT NULL,
[attributeValueString] [nvarchar](400) NULL,
[attributeValueInt] [bigint] NULL,
[attributeValueBinary] [varbinary](800) NULL,
[attributeValueReference] [uniqueidentifier] NULL
[MA_Attributes].[objectId] 是 [MA_Objects].[id] 的 FK
因此,此应用程序需要能够通过查询这些属性值从 MA_Objects 表中找到对象 ID。搜索可能就像查找邮件地址为“test@test.com”的用户一样简单,也可能是存储在两个表中的属性的复杂组合(混合了 AND 和 OR 条件)。
MA_Objects 表中将有大约 500k 条记录。 MA_Attributes 表中将有数千万条记录。性能很重要。
我的问题是,我最好使用嵌套的 SELECT 子查询还是一系列自联接来实现这一点?还是完全不同的东西?两者似乎都有效,但我无法理解实际的查询计划以了解幕后发生的事情。
这是两种格式的相同查询
子查询模型
select distinct
[o].[id]
from [dbo].[MA_Objects] [o]
left join [dbo].[MA_Attributes] [a]
on ([o].[id] = [a].[objectId])
where
(
[o].[objectClass] = N'user'
and
(
(
[o].[supervisor] in ('6213F48A-A97F-48E2-AFD7-2EF830C4DAA8', '0917EC45-CA23-41F5-911C-B92A90140AFD', '69B1DA67-4E3C-406E-8B78-B4633800B491')
)
and
(
[o].[id] in
(
select [a].[objectId]
from [dbo].[MA_Attributes] [a]
where
(
(
[a].[attributeName] = N'mailAlternateAddresses'
and
[a].[attributeValueString] in (N'test.test@test.com', N'test3.test3@test.com')
)
)
)
)
and
(
[o].[id] in
(
select [a].[objectId]
from [dbo].[MA_Attributes] [a]
where
(
(
[a].[attributeName] = N'objectSids'
and
[a].[attributeValueBinary] in (0x0001020304, 0x0007070707)
)
)
)
)
and
(
[o].[id] in
(
select [a].[objectId]
from [dbo].[MA_Attributes] [a]
where
(
(
[a].[attributeName] = N'expiryDates'
and
[a].[attributeValueInt] in (44, 77, 99)
)
)
)
)
)
)
自连接模型
select distinct
[o].[id]
from [dbo].[MA_Objects] [o]
left join [dbo].[MA_Attributes] [a]
on ([o].[id] = [a].[objectId])
where
(
[o].[objectClass] = N'user'
and
(
(
[o].[supervisor] in ('6213F48A-A97F-48E2-AFD7-2EF830C4DAA8', '0917EC45-CA23-41F5-911C-B92A90140AFD', '69B1DA67-4E3C-406E-8B78-B4633800B491')
)
and
(
[o].[id] in
(
select [a].[objectId]
from [dbo].[MA_Attributes] [a]
left join [dbo].[MA_Attributes] [a0] on ([a].[objectId] = [a0].[objectId])
left join [dbo].[MA_Attributes] [a1] on ([a].[objectId] = [a1].[objectId])
left join [dbo].[MA_Attributes] [a2] on ([a].[objectId] = [a2].[objectId])
where
(
[a].[objectId] = [a0].[objectId]
and
[a].[id] <> [a0].[id]
and
[a].[objectId] = [a1].[objectId]
and
[a].[id] <> [a1].[id]
and
[a].[objectId] = [a2].[objectId]
and
[a].[id] <> [a2].[id]
and
(
(
[a0].[attributeName] = N'mailAlternateAddresses'
and
[a0].[attributeValueString] in (N'test.test@test.com', N'test3.test3@test.com')
)
and
(
[a1].[attributeName] = N'objectSids'
and
[a1].[attributeValueBinary] in (0x0001020304, 0x0007070707)
)
and
(
[a2].[attributeName] = N'expiryDates'
and
[a2].[attributeValueInt] in (44, 77, 99)
)
)
)
)
)
)
)
【问题讨论】:
标签: sql-server tsql query-optimization