MS SQL 查询性能 - 在 vs table 变量中
MS SQL query performance - in vs table variable
我有一些字符串列表(字符串的数量从 10 到 100 不等),我需要从一些大的 table(100K-5M 记录)中获取 select 值
尽我所能。
在我看来,我基本上有 3 个选项——使用 'in' 子句,使用 table 变量或使用临时 table。
像这样:
select col1, col2, col3, name from my_large_table
where index_field1 = 'xxx'
and index_field2 = 'yyy'
and name in ('name1', 'name2', 'name3', ... 'nameX')
或
declare @tbl table (name nvarchar(50))
insert @tbl(name) values ('name1', 'name2', 'name3', ... 'nameX')
select col1, col2, col3, name
from my_large_table inner join @tbl as tbl on (tbl.name = my_large_table.name)
where index_field1 = 'xxx'
and index_field2 = 'yyy'
大 table 在 (index_field1, index_field2, name, index_field3) 上有聚簇索引。
实际上,对于每组名称,我有 4-5 个来自大型 table 的查询:
select,然后根据某种逻辑更新 and/or 插入 and/or 删除 - 每次都将查询限制在这组名称上。
名称集和查询是在.net客户端中动态构建的,因此不存在可读性、代码简单性等类似问题。唯一的目标是达到最佳性能,因为这个批处理将被执行很多次。
所以问题是——我应该使用 'in' 子句、table 变量还是其他东西来写我的条件?
如前所述,您应该避免对非常大的数据使用 table 变量,因为它们不允许索引(更多详细信息 here)。
如果我没记错的话,您有多个查询使用同一组名称,所以我建议采用以下方法:
1) 创建一个持久性 table (BufferTable
) 来保存单词列表:PkId, SessionId, Word
.
2) 每个会话使用一些词组:bulk insert 你的词在这里(SessionId 对于每批查询都是唯一的)。几十个字应该很快了
3) 像下面这样写您的查询:
select col1, col2, col3, name
from my_large_table LT
join BufferTable B ON B.SessionId = @SessionId AND name = B.Word
where LT.index_field1 = 'xxx'
and LT.index_field2 = 'yyy'
4) 需要 SessionId 索引才能获得最佳性能。
这样,您就不必为每个查询推送单词。
BufferTable
最好定期清空,因为删除很昂贵(当没有人在上面做某事时截断它是一种选择)。
我有一些字符串列表(字符串的数量从 10 到 100 不等),我需要从一些大的 table(100K-5M 记录)中获取 select 值 尽我所能。 在我看来,我基本上有 3 个选项——使用 'in' 子句,使用 table 变量或使用临时 table。 像这样:
select col1, col2, col3, name from my_large_table
where index_field1 = 'xxx'
and index_field2 = 'yyy'
and name in ('name1', 'name2', 'name3', ... 'nameX')
或
declare @tbl table (name nvarchar(50))
insert @tbl(name) values ('name1', 'name2', 'name3', ... 'nameX')
select col1, col2, col3, name
from my_large_table inner join @tbl as tbl on (tbl.name = my_large_table.name)
where index_field1 = 'xxx'
and index_field2 = 'yyy'
大 table 在 (index_field1, index_field2, name, index_field3) 上有聚簇索引。
实际上,对于每组名称,我有 4-5 个来自大型 table 的查询: select,然后根据某种逻辑更新 and/or 插入 and/or 删除 - 每次都将查询限制在这组名称上。
名称集和查询是在.net客户端中动态构建的,因此不存在可读性、代码简单性等类似问题。唯一的目标是达到最佳性能,因为这个批处理将被执行很多次。 所以问题是——我应该使用 'in' 子句、table 变量还是其他东西来写我的条件?
如前所述,您应该避免对非常大的数据使用 table 变量,因为它们不允许索引(更多详细信息 here)。
如果我没记错的话,您有多个查询使用同一组名称,所以我建议采用以下方法:
1) 创建一个持久性 table (BufferTable
) 来保存单词列表:PkId, SessionId, Word
.
2) 每个会话使用一些词组:bulk insert 你的词在这里(SessionId 对于每批查询都是唯一的)。几十个字应该很快了
3) 像下面这样写您的查询:
select col1, col2, col3, name
from my_large_table LT
join BufferTable B ON B.SessionId = @SessionId AND name = B.Word
where LT.index_field1 = 'xxx'
and LT.index_field2 = 'yyy'
4) 需要 SessionId 索引才能获得最佳性能。
这样,您就不必为每个查询推送单词。
BufferTable
最好定期清空,因为删除很昂贵(当没有人在上面做某事时截断它是一种选择)。