Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 优化复杂表。pytables中的where()查询?_Python_Pytables - Fatal编程技术网

Python 优化复杂表。pytables中的where()查询?

Python 优化复杂表。pytables中的where()查询?,python,pytables,Python,Pytables,我有一个非常大的数据库——我正在处理一个3.5亿行的子集,但最终它将是大约3亿行。我在这里的全部目标是优化这个数据库上的一种特定类型的查询,这几乎牺牲了除内存之外的一切。我现在使用的db文件是在PyTables版本2.3.1的1级上用blosc压缩的(如果有帮助的话,我可以更新)。每行有13个条目-一个典型条目如下所示: ['179', '0', '1', '51865852', '51908076', '42224', '22', '2', '20', '22', '2', '0.051691

我有一个非常大的数据库——我正在处理一个3.5亿行的子集,但最终它将是大约3亿行。我在这里的全部目标是优化这个数据库上的一种特定类型的查询,这几乎牺牲了除内存之外的一切。我现在使用的db文件是在PyTables版本2.3.1的1级上用blosc压缩的(如果有帮助的话,我可以更新)。每行有13个条目-一个典型条目如下所示:

['179', '0', '1', '51865852', '51908076', '42224', '22', '2', '20', '22', '2', '0.0516910530103', '0.0511359922511']
它们都是数字,但不一定是同一类型。我目前将它们存储在PyTables表中,定义如下:

ind = tables.UInt16Col(pos=0)
hap = tables.UInt8Col(pos=1)
chrom = tables.UInt8Col(pos=2)
hap_start = tables.Int32Col(pos=3)
hap_end = tables.Int32Col(pos=4)
hap_len = tables.Int16Col(pos=5)
mh_sites = tables.Int16Col(pos=6)
mh_alt = tables.Int16Col(pos=7)
mh_n_ref = tables.Int16Col(pos=8)
all_sites = tables.Int16Col(pos=9)
all_alt = tables.Int16Col(pos=10)
freq = tables.Float32Col(pos=11)
std_dev = tables.Float32Col(pos=12)
我真的不在乎建立这个数据库需要多长时间——我最终会创建一次,然后访问它。我的问题如下:

a = [ x[:] for x in hap_table.where('''(mh_sites == 15) & (hap_len > 25000) & (hap_len < 30000) & (freq > .38) & (freq < .4) & (std_dev > .3) & (std_dev < .4)''')]
如果我没有事先索引,则为10秒。我不太明白为什么索引数据库上的查询速度较慢。。也许索引会产生不必要的开销

正如我所说,我的目标是尽可能地优化这种类型的查询——基本上以牺牲除内存使用以外的一切为代价(我想使用大约2G,实际上不想使用超过5G)。我尝试了索引,但似乎不起作用。我所有的查询都是针对mh_站点的单个值,并且只有大约100个可能的值,因此我考虑将其拆分为多个表,因此我在任何时候都只搜索数据的一个子集(尽管我不完全确定如何做,除了mydata.root.table_1、mydata.root.table_2等)。我还考虑过尝试将其存储为一个数组——可能是一个浮点数组,然后在需要时将所有其他内容转换为int?如果有区别,我的查询通常返回20k到500k的结果


关于优化此查询有什么建议吗?

我找到了如何使其更快的方法-我的解决方案可能会帮助其他人,因此我将其发布在这里

我对PyTables中的索引是如何工作的感到困惑。我认为CSI实际上会对数据进行排序,但事实并非如此——一旦你添加了一组行,它们总是按顺序排列的。对我来说,在插入数据之前对数据进行排序是值得的。我的查询时间减少了1-2个数量级


这也解释了为什么索引表实际上增加了查询时间——因为行基本上是随机分布的,所以我需要为每个查询读取整个数据库。因此,pytables是否可以使用索引来确定哪些块是需要读取的并不重要,因为它无论如何都需要读取所有块。因此,索引只是在数据未排序时增加了开销。对于已排序的表,索引肯定会有所帮助。

如果数据集在追加之前排序过大,则不可能总是进行排序。在这种情况下,您可以创建一个CSI索引,然后使用sortby关键字复制该表,然后将行按正确的顺序排列,而不必在内存中保存完整的数据集。时间可能是个问题,因为以排序方式复制集合需要很长时间。但是,在一次编写并经常查询的情况下,这可能是值得的。PyTables文档中也提到了这一点:
byteorder := 'little'
chunkshape := (32768,)
autoIndex := True
colindexes := {
  "hap_len": Index(6, medium, shuffle, zlib(1)).is_CSI=False,
  "freq": Index(6, medium, shuffle, zlib(1)).is_CSI=False,
  "std_dev": Index(6, medium, shuffle, zlib(1)).is_CSI=False,
  "mh_sites": Index(6, medium, shuffle, zlib(1)).is_CSI=False}