是否可以在列长度或任何sql函数上创建非聚集索引

时间:2016-12-02 13:18:23

标签: sql sql-server

我在这个网站上搜索过,我查看了类似的问题,我没有找到答案,我确定它在某个地方,但我没有找到它,我的问题是,我有一个表名为Maps,此表包含数百万行,此表包含索引: imagename 列上的ClusteredIndex和 imagename 列上的NonClusteredIndex以及已下载专栏,

以下查询执行0:

private static void OpenPaint()
{
    Process.process = new Process();
    process.StartInfo.FileName = "mspaint.exe";
    process.StartInfo.WindowStyle = "ProcessWindowStyle.Maximized;
    process.Start();
}

结果 - > 100个

此外,以下查询执行0:

SELECT top 100 imagename 
from [maps] 
where imagename='SomeExistingImageName' 
and downloaded is null

结果 - > 0

但是当我尝试运行以下查询时,执行时需要02min08s:

SELECT top 100 imagename 
from [maps] 
where imagename='SomeRandomNameThatDoesNotExistOnMyDatabase' 
and donwloaded is null

结果 - > 0(因为没有满足这些条件的图像名称)

另一个例子,当我将10改为17时,执行需要0:

SELECT top 100 imagename 
from [maps] 
where LEN(imagename)=10
and downloaded is null

结果 - > 100个

我的问题是什么是提高此类查询性能的最佳方法(查询列长度)?是否可以在LEN(imagename)上创建另一个NonClusteredIndex?如果答案是肯定哪个列应该参与?

PS:我的表包含超过500M的条目

2 个答案:

答案 0 :(得分:3)

您可以使用虚拟列

alter table [maps] add len_imagename as (len(imagename))
create index maps_ix_len_imagename on [maps] (len_imagename)

演示

;with t(i) as (select 1 union all select i+1 from t where i<10)
select  replicate('x',rand(cast(newid() as varbinary))*1000)    AS i
into    #t
from    t t0,t t1,t t2,t t3,t t4,t t5,t t6
option  (maxrecursion 0)

alter table #t add len_i as (len(i))

create index #t_ix_len_i on #t (len_i)

select count(*) from #t where len_i between 99 and 101

enter image description here

答案 1 :(得分:0)

这个对我有用:

alter table [maps] add len_imagename as (len(imagename));
create index [maps] on [maps] (len_imagename) include([downloaded]);

以下查询的执行时间为0:

SELECT top 100 imagename 
from [maps] 
where LEN(imagename)=10
and downloaded is null