【问题标题】:Search with index is slower than without index in pytables when the result is large当结果很大时,在 pytables 中使用索引搜索比没有索引慢
【发布时间】:2014-01-13 05:21:20
【问题描述】:

以下代码创建一个测试hdf5文件:

from tables import *

class KeyValue(IsDescription):
    key = StringCol(itemsize=30, dflt=" ", pos=0)  # character String
    value = Int64Col(dflt=0, pos=1)

f = open_file("keyvalue.h5", "w")    
kv = f.create_table("/", "keyvalues", KeyValue)

import string
import random

for j in range(20):
    values = []
    for i in xrange(100000):
        key = "".join(random.sample(string.uppercase, 5))
        value = random.randint(0, 1000000)
        values.append((key, value))
    kv.append(values)

f.close()

这里是速度测试代码:

f = open_file("keyvalue.h5", "a")
kv = f.root.keyvalues

kv.cols.value.remove_index()

print "without index"
%timeit a = kv.read_where('value < 10')
%timeit a = kv.read_where('value < 1000')

kv.cols.value.create_csindex()

print "with index"
%timeit a = kv.read_where('value < 10')
%timeit a = kv.read_where('value < 1000')

f.close()

输出是:

without index
10 loops, best of 3: 66.1 ms per loop
10 loops, best of 3: 109 ms per loop
with index
10000 loops, best of 3: 164 µs per loop
10 loops, best of 3: 121 ms per loop

查询'value

我想知道这是怎么发生的,您能否将timeit 结果发布到您的 机器?

【问题讨论】:

  • 请注意,您的代码示例似乎在 ipython 中,而不是纯 python。

标签: python indexing hdf5 pytables


【解决方案1】:

所以这很可能会发生,因为当您要查询的总数据集只有一小部分时,索引效果最好。在您给出第一个查询的示例中,value &lt; 10 满足此约束并且查询速度更快。第二个查询,value &lt; 1000,刚好在这个约束的尖端,因此速度慢了一点。 “小”的含义可能取决于您的数据集。因此,值得获取一些时间信息来帮助您做出决定。

正如您在this notebook that I made 中看到的,随着您增加值范围的子集,查询变得越来越慢。对于您的特定操作(少于一个数字),当然可以对索引进行优化,这些优化不适用于其他类型的索引。现在存在的索引可以处理更广泛的用例和查询。这可能值得在 pytables-dev 邮件列表中提出。

更新:

时序图:

【讨论】:

  • 谢谢解答,我放假了,没有电脑和手,能不能加个无索引的时序图。我会询问 pytables-dev 邮件列表。当结果很大时,创建结果需要更多时间,因此查询变得越来越慢是有意义的。但它不应该比没有索引慢。
  • 添加了图片!而且它更慢,因为在索引时它必须引用索引数组以及值数组。当只是进行查询时,它只查看值数组。这基本上意味着它使用的算法对于您的用例来说不是最佳的。可能有办法解决这个问题。
【解决方案2】:

我遇到过同样的问题,我认为这与我创建的这个问题有关:

https://github.com/PyTables/PyTables/issues/187

https://groups.google.com/d/msg/pytables-users/oQIO2hJdB6U/Oo3iDNlmN1sJ

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-28
    • 2012-02-28
    • 2013-06-24
    • 1970-01-01
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多