哪些索引实现可以处理任意列组合?

时间:2009-10-16 15:11:49

标签: sql database indexing

我正在开发一个带有Web界面的小型数据仓库系统,人们可以在这里进行过滤搜索。目前大约有50列人们可能希望过滤,大约250万行。表扫描速度很慢。麻烦的是,我得到的查询范围没有共同的前缀。

现在我正在使用sqlite3,如果所需的列是该索引中最左边的列,则只使用索引。这似乎意味着我需要很多索引。快速浏览一下MySQL表明,这种查询还需要很多索引。

我的问题是什么索引实现可用于不同的数据库系统,可以处理任意列组合的这种查询?

我已经制作了自己的索引方案原型;我存储额外的表,列出我的大表中的整数主键,每个列的每个值出现,我保留足够的统计数据,以便能够首先检查具有最小匹配数的值。它运作正常;比表扫描好得多,但仍然有点慢,这对于Python执行许多SQL查询的第一个版本来说并不令人惊讶。

4 个答案:

答案 0 :(得分:2)

column-oriented databases在每列基础上存储数据,其中每列都是自己的索引。它们非常适合数据仓库,因为它们读取速度极快,但更新速度相当慢。

Kickfire就是这样一个例子,它是一个定制的MySQL引擎,并以令人印象深刻的系统成本保持了TPC-H benchmark最高冠军数周。请注意,Kickfire是一种设备,作为硬件盒出售。

Infobright将是另一个类似的示例,并且具有在Windows和Linux上运行的免费community edition

答案 1 :(得分:1)

当为表创建的索引太多时,我通常会回到全文搜索。但不能说它是否适合您的情况。

答案 2 :(得分:0)

人们应该考虑引入基于SQL表的“本土”索引结构作为最后的手段,即如果仍然存在[业务明智的]查询案例,而传统的索引设置没有正确处理。例如,如果这些索引的列表变得很大等等。

一些观察
您不一定需要包含所有列的索引,这些列可能涉及一个特定查询;只有[集体]选择性的可能是必需的。

换句话说,如果查询使用例如a,b,c和d列,但是如果存在a和b的索引,并且如果它产生,统计上只有几千行,则可以接受< em> not 引入带有a,b和c(或者d或两者)的索引,如果c或d不是非常合理的搜索条件(不经常使用),并且如果它们的宽度太大会导致过度负担a + b索引(或者如果有其他列更适合“加入”a + b索引)。

除了他们对磁盘存储的明显额外需求之外,附加索引虽然可能有助于SELECT(读取)操作,但也可能成为CUD(创建/更新/删除)操作的障碍。看来这里的上下文类似于数据仓库,很少有[计划外的] CUD操作发生,但记住这一点很好。

有关SQLite确定特定查询执行方式的方式的宝贵见解,请参阅SQLite Optimizer

制作索引列表
此应用程序的索引方案的暂定 基础 可能如下所示:

  • [A]表格中每列的单列索引(除了那些非常不可选择的列,比如说“结婚”列中带有“Y / N”值......)
  • [B]每个可能/常见用例查询的两(或三)列索引
  • [C]其他两个/三个列索引,用于某些非常见查询案例涉及一组列的情况,这些列都不是单独选择的。

在此基础上,我们可以定义所需索引的实际列表

  • 在上面的[B]索引的末尾添加一个(或几个)额外的列(以及经过深思熟虑的顺序...)。通常选择这样的柱子是因为它们的宽度相对较小(它们确实会过度增长指数),并且因为它们与索引中引用的柱子结合使用它们的相对机会。
  • 删除通常等同于一个或多个[B]索引的[A]索引。即:以相同列开头的列,并且额外的列不会给索引带来太多负担。
  • 审查所有可能(或所有可接受的)案例的TREE,并用上述索引标记充分服务的分支。然后为不易覆盖的奇数用例添加更多索引(如果仅使用部分索引扫描+主表查找可接受的行数)。

在这种情况下,我发现一个手写树结构是一个有用的工具,可以帮助管理其他无法管理的可能组合列表。假设从问题中指出的50个列中选择最多4个搜索条件,我们考虑超过230,000个组合......树有助于快速修剪它。

答案 3 :(得分:0)

SInce数据仓库通常针对读取不写入数据的数据进行了优化,我会考虑简单地索引所有列。是的,这会减慢数据进入仓库的速度,但通常会在非高峰时段发生,而且每天只发生一次或更少。