我有一个包含许多列的大型SQL Server表。我试图优化这个表,以获得最小的存储空间,因为查询并不经常进行。
但是,最近我被要求查询这个表,以查找特定的GUID。
由于空间限制,我不想在GUID上放置索引,因为这将使用许多GB的存储空间。
有没有办法可以在列上添加索引,但只在前2个字符上添加索引?
这应该足以将数据集减少到足够小的数量,然后进行物理读取?导致速度和存储空间之间的混合。
简而言之,如果我有一个名为ID的varchar(36)列,我可以只在该列的前两个字符上添加索引吗?
create index(2) on ID发布于 2017-09-18 14:40:14
如果我有一个名为ID的varchar(36)列,我只能在该列的前两个字符上添加索引。
是的,您的can..this类型的索引称为计算索引...
下面是一些测试数据,用于演示如何在计算列上创建计算列和索引
create table t12
(
id varchar(36) default CONVERT(varchar(36), NEWID())
)
insert into t12
default values
go 100
--add computed column
alter table t12
add col2 as left(id,2)
--create index
create index nci on t12(col2)
select col2 from t12 where col2='30'-this does a index seek要在计算列上创建索引,它必须满足here中解释的一些属性,您可以检查列是否满足这些属性
SELECT
COLUMNPROPERTY( OBJECT_ID('DBO.t12'), 'col2','IsComputed') AS IsComputed,
COLUMNPROPERTY( OBJECT_ID('DBO.t12'), 'col2','IsDeterministic') AS IsDeterministic,
COLUMNPROPERTY( OBJECT_ID('DBO.t12'), 'col2','IsPrecise') AS IsPrecise,
COLUMNPROPERTY( OBJECT_ID('DBO.t12'), 'col2','IsIndexable') AS IsIndexable如果为IsPRecise property is not satisfied,则可能必须持久存储该列,这可能会占用空间
备注:
在大型列上创建计算索引可能需要巨大的内存才能进行排序(使用:sort in tempdb选项),并且可能会耗尽内存。我试图对260亿行数据(历史数据)创建计算索引,但失败了
新计算列不是唯一的
发布于 2017-09-18 15:11:18
您可以索引int列而不是varchar(36),并且可以节省两倍以上的空间。下面的示例演示了这一点:
use [tempdb];
if object_id('tempdb..#t1') is not null drop table [#t1];
if object_id('tempdb..#t2') is not null drop table [#t2];
-- create tables
create table [#t1] ([guid] varchar(36), [guid_int] int);
create table [#t2] ([guid] varchar(36), [guid_int] int);
-- dummy data
;with data as (select top 10000 [guid] = newid() from sys.columns t1 cross apply sys.columns t2) insert into [#t1] select [guid], convert(int, convert(binary, [guid])) from [data];
;with data as (select top 10000 [guid] = newid() from sys.columns t1 cross apply sys.columns t2) insert into [#t2] select [guid], convert(int, convert(binary, [guid])) from [data];
-- create indexes
create nonclustered index [ix_#t1_guid] on [#t1]([guid]);
create nonclustered index [ix_#t2_guid_int] on [#t2]([guid_int]);
-- check space used
exec sp_spaceused N'tempdb..#t1';
exec sp_spaceused N'tempdb..#t2'; 使用int列而不是varchar(2)您有: a)更多唯一性b) int索引大小小于varchar(2)
https://stackoverflow.com/questions/46272791
复制相似问题