4

我有一个包含大约五个可能的索引列的数据库,所有这些列都以不同的方式有用。我们称它们为 System、Source、Heat、Time 和 Row。一起使用 System 和 Row 将生成一个唯一键,如果按 System-Row 排序,数据库还将针对五个索引变量的任意组合进行排序(按照我上面列出的顺序)。

我的问题是我使用这些列的所有组合:有时我想将每个系统行加入下一个系统(行 + 1),有时我想通过系统源热进行 GROUP 或 WHERE,有时我想查看 System-Source WHERE Time is in a specific window 的所有条目等。

基本上,我想要一个索引结构,其功能类似于这五个索引的每个可能的排列(当然,以正确的顺序),而不是实际进行每个排列(尽管如果有必要我愿意这样做)。我正在做统计/分析,而不是传统的数据库工作,因此索引的大小和创建/更新它的速度不是问题;我只关心加快我的即兴查询,因为我倾向于思考它们,运行它们,等待 5-10 分钟,然后再也不使用它们。因此,我主要关心的是将“等待 5-10 分钟”减少到更像“等待 1-2 分钟”。

我的排序数据看起来像这样:

Sys So H Ti R
1   1  0 .1 1
1   1  1 .2 2
1   1  1 .3 3
1   1  2 .3 4
1   2  0 .5 5
1   2  0 .6 6
1   2  1 .8 7
1   2  2 .8 8

编辑:它可能会简化一些事情,系统实际上总是需要作为第一列包含在内,以使其他 4 列中的任何一个按排序顺序排列。

4

2 回答 2

0

如果您关心 SELECT 速度而不关心 INSERT,那么您可以将所有组合具体化为 INDEXED 视图。您只需要原始表的 24 倍的存储空间,制作一张表和 23 个 INDEXED VIEW,每个 5 列。

例如

create table data (
    id int identity primary key clustered,
    sys int,
    so int,
    h float,
    ti datetime,
    r int);
GO
create view dbo.data_v1 with schemabinding as
    select sys, so, h, ti, r
    from dbo.data;
GO
create unique clustered index cix_data_v1 on data_v1(sys, h, ti, r, so)
GO
create view dbo.data_v2 with schemabinding as
    select sys, so, h, ti, r
    from dbo.data;
GO
create unique clustered index cix_data_v2 on data_v2(sys, ti, r, so, h)
GO

-- and so on and so forth, keeping "sys" anchored at the front

但是请注意
问:为什么查询优化器没有拾取我的索引视图以用于查询计划?(在链接文章中搜索)


如果空间是一个问题,那么下一个最好的办法是在 4 列中的每一列上创建单独的索引,以系统开头,即 (sys,ti)、(sys,r) 等。如果有帮助,这些可以一起使用查询,否则它将恢复为全表扫描。

于 2012-10-31T20:43:14.460 回答
0

很抱歉花了一段时间才回到这个问题上,我不得不在其他几个星期内工作。无论如何,在尝试了一堆事情之后(包括这里建议的所有内容,甚至是蛮力的“为每个排列创建索引”方法),我还没有找到任何可以显着提高性能的索引方法。

但是,我找到了一个替代的非索引解决方案:只选择我感兴趣的行和列到中间表中,然后使用它们而不是完整的表(所以我使用大约 5 百万行 6 列代替30 百万行 35 列)。最初的选择和表创建有点慢,但是之后的步骤要快得多,即使我只运行一次,我实际上也节省了时间(考虑到我改变事物的频率,通常不止一次)。

我怀疑这种巨大改进的原因对于大多数 SQL 用户来说是显而易见的(可能与页面文件大小有关),如果是这样,我深表歉意。我唯一的借口是,我是一名统计学家,试图自学如何做到这一点,虽然我很擅长(最终)完成我想做的事情,但我对它的机制的理解是如何的done 非常接近“这是一个神奇的黑匣子,别担心”。

于 2012-11-16T19:47:48.867 回答