我正在开发一个带有Web界面的小型数据仓库系统,人们可以在这里进行过滤搜索。目前大约有50列人们可能希望过滤,大约250万行。表扫描速度很慢。麻烦的是,我得到的查询范围没有共同的前缀。
现在我正在使用sqlite3,如果所需的列是该索引中最左边的列,则只使用索引。这似乎意味着我需要很多索引。快速浏览一下MySQL表明,这种查询还需要很多索引。
我的问题是什么索引实现可用于不同的数据库系统,可以处理任意列组合的这种查询?
我已经制作了自己的索引方案原型;我存储额外的表,列出我的大表中的整数主键,每个列的每个值出现,我保留足够的统计数据,以便能够首先检查具有最小匹配数的值。它运作正常;比表扫描好得多,但仍然有点慢,这对于Python执行许多SQL查询的第一个版本来说并不令人惊讶。
答案 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。
制作索引列表
此应用程序的索引方案的暂定 基础 可能如下所示:
在此基础上,我们可以定义所需索引的实际列表:
在这种情况下,我发现一个手写树结构是一个有用的工具,可以帮助管理其他无法管理的可能组合列表。假设从问题中指出的50个列中选择最多4个搜索条件,我们考虑超过230,000个组合......树有助于快速修剪它。
答案 3 :(得分:0)
SInce数据仓库通常针对读取不写入数据的数据进行了优化,我会考虑简单地索引所有列。是的,这会减慢数据进入仓库的速度,但通常会在非高峰时段发生,而且每天只发生一次或更少。