【问题标题】:Index structure to maximize speed across any combination of index columns索引结构可最大限度地提高任何索引列组合的速度
【发布时间】:2012-10-31 19:21:26
【问题描述】:

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

我的问题是我使用这些列的所有组合:有时我想将每个 System-Row 加入到下一个 System-(Row+1),有时我想通过 System-Source-Heat 进行 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 列中的任何一个按排序顺序。

【问题讨论】:

标签: sql sql-server indexing


【解决方案1】:

如果您关心 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

但是请注意
Q. Why isn't my indexed view being picked up by the query optimizer for use in the query plan?(在链接的文章中搜索)


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

【讨论】:

  • 好的,我的立场是正确的:空间可能是的问题。如果我的索引集合是原始表大小的 2-3 倍,这没什么大不了的,但 24 倍将开始进入 TB 范围。另外,我不确定这是否解决了系统源热索引无法帮助仅基于系统源的搜索的问题。
  • 抛开空间,system-source-heat-time 确实帮助system-source 查询。它可能不如system-source-heatsystem-source 索引那么有效,但作为一个聚集索引,它可能只是一个或两个边缘,如果您查询2 列但同时检索其他列。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 2017-02-16
    相关资源
    最近更新 更多