Attributes

What are attributes?

Attributes are a kind of metadata that you can apply to lists that lets kdb+/q know that the values in the list are arranged in a particular way - and with this knowledge it can more efficiently interact with the list. Consider the following two scenarios:

It should be obvious that on average the former will take more time than the latter. In the first scenario, there is little choice but to pick a starting point and work through the list one by one. In the second scenario, starting in the middle and checking if that number is greater or less than 14 will mean that half the list can be discarded. 

We have gained some information about how the list is arranged and this has allowed us to more efficiently interact with it. The concept is the same in kdb+/q with attributes. Indeed the example above is an example of using the 'sorted' attribute. The attributes available are:

Applying and using attributes

How to apply attributes

To apply or remove an attribute to a list, the syntax is as follows:

/ Method 1

q)l:1 2 3 4 5 6


q)`s#l /sorted

`s#1 2 3 4 5 6


q)`u#l /unique

`u#1 2 3 4 5 6


q)`p#l /parted

`p#1 2 3 4 5 6


q)`g#l /grouped

`g#1 2 3 4 5 6


/ Method 2

q)@[`.; `l; `s#]

`.

q)l

`s#1 2 3 4 5


/ Remove

q)l

`g#1 2 3 4 5 6

q)`#l /removed

1 2 3 4 5 6

Note that when the attribute has been applied, the list is prepended with e.g. `g# to signify this. 

If the attribute is denoting certain characteristics of the list, such as it being sorted, then:

q)l:6 1 2 3 4 5


q)`s#l /sorted

's-fail

  [0]  `s#l /sorted

q)l:`s#1 2 3 4 5 /sorted


q)l,:3


q)l /attribute lost

1 2 3 4 5 3

Why use attributes?

Certain operations are more efficient on lists with attributes applied. When a list has the sorted attribute applied, kdb+/q will use binary search for '?' search operations. This can provide a drastic increase in search performance:

q)l:10000000?10000

q)lSorted:`s#asc l


q)\t:100 l?til 1000

2875

q)\t:100 lSorted?til 1000

22


/ What else runs faster?

q)\t:100 l>1000

907

q)\t:100 lSorted>1000

35

Most of the time, attributes are applied to columns in tables to allow more efficient querying. As columns of tables are just normal lists, an attribute can be applied to a table as so:

q)t:([]sym:1000000?`2; price:1000000?100)

q)tSorted:update `s#price from `price xasc t

Performing a 'meta' on the table now returns a value in the 'a' column denoting which column/s have attributes applied:

q)meta tSorted

c    | t f a

-----| -----

sym  | s

price| j   s

And now that the column has the sorted attribute applied, as expected the lookup on that column is faster:

q)\t:100 select count i from t where price>25

173


q)\t:100 select count i from tSorted where price>25

97

When to use attributes

The logical conclusion at this point would be to use attributes all the time on as many columns as possible. However there are some drawbacks:

Therefore attributes should only be used when they will actually provide a performance improvement - testing is important to determine this. 

The most frequently used attribute you will see in historical databases is the 'parted' attribute (on sym, and potentially the grouped attributes on other cols) and for in-memory tables it is likely to be the 'grouped' attribute, for example in the Tickerplant

Attributes

Read more about individual attributes here:

Attributes within the Tick Framework

One stop cheat sheet

Useful Links