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

Uts*_*Uts 1 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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

在以下查询中运行时:
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 
Run Code Online (Sandbox Code Playgroud)

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

Sam*_*len 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
Run Code Online (Sandbox Code Playgroud)

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

\ts:100 select last i from t where date=.z.d-5
Run Code Online (Sandbox Code Playgroud)

将运行查询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

Run Code Online (Sandbox Code Playgroud)

同样,假设有问题的表已分区,将显示所示查询.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| ()
Run Code Online (Sandbox Code Playgroud)

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

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

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

(#:;`i)
Run Code Online (Sandbox Code Playgroud)

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

  1. 往上看。

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

  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
Run Code Online (Sandbox Code Playgroud)

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