If you only have one record per sym and date then you can construct a table of the syms and dates that you want, then use that with asof. However, be aware that it will be a <= match - so if you require exact match the it?s not what you want.
In terms of your query then within will speed things up:
q)n:10000000
q)t:update p#sym from sym xasc t:(sym:n?-100?`4; date:asc n?2015.01.01;price:n?100f)
q)\t:1000 select from t where sym=`adkk,date within 2010.01.01 2010.04.01
120
q)\t:1000 select from t where sym=`adkk,date>2009.12.31, date<2010.04.02
195
In terms of utilising the fact that date is sorted within each sym, the within operation is optimised for sorted lists but to flag the list as sorted probably adds to much overhead:
q)\t:1000 select from t where sym=adkk,(s#date) within 2010.01.01 2010.04.01
168
You can sometimes do tricky things with i and bin on sorted columns to speed things up, but I don?t think this technique can be utilised here because i is global to the table rather than for the sub-selected sample
q)t1:`date xasc t
q)\t:1000 a:select from t1 where date within 2010.01.01 2010.04.01
547
(I?m not sure if the edge cases are quite right here but you get the idea)
q)\t:1000 b:select from t1 where i within 1 0 + date bin 2009.12.31 2010.04.01
Here’s another solution that has quite a significant speedup versus the select query, but it requires the table be resorted by date and a g# applied to the sym column, and the table to be in-memory. The in-memory requirement is because an in-memory g# gives instant access to group[t`sym].
q)n:10000000
q)t:update p#sym from sym xasc t:(sym:n?-100?`4; date:asc n?2015.01.01;price:n?100f)
q)\t:1000 select from t where sym=`adkk,date within 2010.01.01 2010.04.01
489
q)update g#sym from date xasc `t;
q)f:{t i {x+til y-x}. 1+(i:group[tsym][x]) bin t[date] bin -1 0+y,z}
q)\t:1000 r:f[`adkk;2010.01.01;2010.04.01]
37
q)r~select from t where sym=`adkk, date within 2010.01.01 2010.04.01