q kdb中表中应用于“ i”列的属性-性能

时间:2019-05-21 04:46:23

标签: kdb

当我在查询下面运行以获取表的计数时,运行查询所需的大小和时间几乎相同。 /表t有97029条记录和124列

Q.1。 -下面的查询中的第i列是否使用has函数在内部使用唯一属性在恒定时间内返回输出?

\ts select last i from t where date=.z.d-5 / 3j, 1313248j 
/ time taken to run the query and memory used is always same not matter how many times we run same query

当我在以下查询中运行时:
第一次,所需的时间和内存很高,但是从下一次运行开始,所需的时间和内存却很少。

Q.2。第一次运行查询时,kdb是否缓存输出,并在下次显示来自缓存的输出?

Q.3在查询下面运行时,是否在第i列上应用了属性,如果是,那么是哪个?

\ts select count i from t where date=.z.d-5 / 1512j, 67292448j
\ts select count i from t where date=.z.d-5 / 0j, 2160j

在以下查询中运行时:
Q.4在查询下方运行时,第i列是否应用了任何属性?

\ts count select from t where date=.z.d-5 / 184j, 37292448j 
 /time taken to run the query and memory used is always same not matter how many times we run 

Q.5以下哪个查询应用于获取记录数量很高的表的列?其他任何查询都可以更快,更少的内存消耗来获得相同的结果吗?

1 个答案:

答案 0 :(得分:5)

  1. u#列没有应用i属性,可以看到以下内容:
q)n:100000
q)t:([]a:`u#til n)
q)
q)\t:1000 select count distinct a from t
2
q)\t:1000 select count distinct i from t
536

这些查询的时机不是恒定的,只是没有足够的有效数字来查看可变性。使用

\ts:100 select last i from t where date=.z.d-5

将运行查询100次,并突出显示时间不是恒定的。

  1. 第一个查询将请求将更多内存分配给q进程,除非调用垃圾回收(.Q.gc[]),否则它将保持分配给该进程。可以使用.Q.w[]查看内存使用情况统计信息。例如,在一个新会话中:
q).Q.w[]
used| 542704
heap| 67108864
peak| 67108864
wmax| 0
mmap| 0
mphy| 16827965440
syms| 1044
symw| 48993
q)
q)\t b: til 500000000
6569
q)
q).Q.w[]
used| 4295510048
heap| 4362076160
peak| 4362076160
wmax| 0
mmap| 0
mphy| 16827965440
syms| 1044
symw| 48993
q)
q)b:0
q)
q).Q.w[]
used| 542768
heap| 4362076160
peak| 4362076160
wmax| 0
mmap| 0
mphy| 16827965440
syms| 1044
symw| 48993
q)
q)\t b: til 500000000
877
q)
q).Q.w[]
used| 4295510048
heap| 4362076160
peak| 4362076160
wmax| 0
mmap| 0
mphy| 16827965440
syms| 1044
symw| 48993

此外,假设有问题的表已分区,则显示的查询将填充.Q.pn,然后可用于随后获取计数,例如

q).Q.pn
quotes|
trades|
q)\ts select count i from quotes where date=2014.04.25
0 2656
q).Q.pn
quotes| 85204 100761 81724 88753 115685 125120 121458 97826 99577 82763
trades| ()

更详细地讲,.Q.ps在后​​台进行了一些select操作。如果您看第三行:

if[$[#c;0;(g:(. a)~,pf)|(. a)~,(#:;`i)];f:!a;j:dt[d]t;...

这将检查查询的“ a”(select)部分,如果是

(#:;`i)

(即count i)最终运行.Q.dt,运行.Q.cn,该分区获取分区计数。因此,它第一次运行此命令时,它将运行.Q.cn,以获取所有分区的计数。下次运行.Q.cn时,它可以只在字典.Q.pn中查找值,这要快得多。

  1. 请参见上文。

  2. 有关i上的属性,请参见上文。 count是一个单独的操作,不是查询的一部分,并且不会受到列属性的影响,它将表视为一个列表。

  3. 对于磁盘上的表,每一列都应包含一个标头,其中可以以很少的开销获得向量的计数:

q)`:q set til 123
`:q
q)read1 `:q
0xfe200700000000007b000000000000000000000000000000010000000000000002000000000..
q)9#read1 `:q
0xfe200700000000007b
q)`int$last 9#read1 `:q
123i
q)
q)`:q set til 124
`:q
q)9#read1 `:q
0xfe200700000000007c
q)`int$last 9#read1 `:q
124i

不过,读取任何文件通常至少需要1毫秒左右的时间,因此计数如上所述进行了缓存。