Sql 什么索引实现可以处理任意列组合?

Sql 什么索引实现可以处理任意列组合?,sql,database,indexing,Sql,Database,Indexing,我正在开发一个带有web界面的小型数据仓库系统,人们可以在其中进行过滤搜索。目前,人们可能希望筛选大约50列,以及大约250万行。表格扫描速度慢得令人痛苦。问题是我得到的查询范围没有公共前缀 现在我正在使用sqlite3,它只会在需要的列是索引中最左边的列时使用索引。这似乎意味着我需要很多索引。快速浏览一下MySQL,就会发现这种查询也需要很多索引 我的问题是,对于能够处理任意列组合上的此类查询的不同数据库系统,有哪些索引实现可用 我已经原型化了我自己的索引方案;我将列出整数主键的额外表存储在每

我正在开发一个带有web界面的小型数据仓库系统,人们可以在其中进行过滤搜索。目前,人们可能希望筛选大约50列,以及大约250万行。表格扫描速度慢得令人痛苦。问题是我得到的查询范围没有公共前缀

现在我正在使用sqlite3,它只会在需要的列是索引中最左边的列时使用索引。这似乎意味着我需要很多索引。快速浏览一下MySQL,就会发现这种查询也需要很多索引

我的问题是,对于能够处理任意列组合上的此类查询的不同数据库系统,有哪些索引实现可用


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

> P> >只应考虑引入基于SQL表的“自生”索引结构作为最后的手段,即如果仍然存在[商业上合理的]查询用例没有用传统的索引设置来正确处理。例如,如果这样的索引列表变得很大,等等

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

换言之,如果查询使用a、b、c和d列,但如果存在带有a和b的索引,并且在统计上仅产生几千行,则如果c或d不是非常合理的搜索条件(很少使用),则不引入带有a、b和c(或和d或两者)的索引是可以接受的,如果它们的宽度是这样的,那么它会给a+b索引带来不适当的负担(或者如果有其他更适合“附加”到a+b索引的列)

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

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

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

  • [A] 表中的每一列都有一个单列索引(可能除了那些可笑的非选择性的列,比如“已婚”列w/“Y/N”值……)
  • [B] 每个可能/常见用例查询的两(或三)列索引
  • [C] 对于某些非常见查询案例涉及一组列(这些列都不是单独选择的)的情况,添加了两列/三列索引
在此基础上,我们可以定义以下所需的实际索引列表:

  • 在上面的[B]索引的末尾(并以深思熟虑的顺序…)添加一(或几个)额外的列。通常选择这类列是因为它们的宽度相对较小(它们会过度增加索引),并且它们有相对的机会与索引中前面引用的列结合使用
  • 删除通常相当于一个或多个[B]索引的[A]索引。也就是说:以相同的列开始的列,对于这些列,额外的列不会对索引造成太大负担
  • 审查所有可能(或所有可接受)案例的树状结构,并根据上述索引标记适当服务的分支。然后为不容易覆盖的奇数用例添加更多索引(如果仅使用部分索引扫描+主表查找来查找可接受的行数)

在这种情况下,我发现一个手写的树结构是一个有用的工具,可以帮助管理可能组合的不可管理列表。假设最大的4个搜索标准中选择的50个列中指出的问题,我们有超过230000个组合考虑…树有助于快速修剪。

,因为数据仓库通常被优化用于读取不写入数据的数据,所以我只考虑对所有列进行索引。是的,这会减慢将数据放入仓库的速度,但通常会在非高峰时间发生,每天只发生一次或更少的次数。

当需要为表创建太多索引时,我通常会使用全文搜索。但是,不能说它是否适合您的场景。

有一种按列存储数据的方法,其中每列都是自己的索引。它们非常适合数据仓库,因为它们的读取速度非常快,但更新速度相当慢

就是这样一个例子,它是一个定制的MySQL引擎,以令人印象深刻的系统成本占据了数周的榜首。请注意,Kickfire是一种设备,作为硬件盒出售


将是另一个类似的例子,并且有一个在Windows和Linux上运行的免费软件。

值得研究一下,看看它是否解决了您的问题。50个潜在的指数是很大的。是的,50个指数是很大的,但我们看到的更像是50个!索引这很荒谬:)如果数据库系统对单个表select实际使用了多个索引,那就好了,我还没有说服sqlite尝试。否则,使用单列索引可能会使我减少几十万行,并扫描每个POS