using a lookup table in a SQL query with group by ...
# troubleshooting
x
using a lookup table in a SQL query with group by + having clause is extremely slow, it looks like this:
Copy code
# old (<1s)
SELECT user, count(*) FROM events 
WHERE time BETWEEN 0 AND 31 AND location BETWEEN 1000 AND 1005 
GROUP BY user HAVING count(*) > 10

# new (>10s)
SELECT user, count(*) FROM events 
WHERE time BETWEEN 0 AND 31 AND location BETWEEN 1000 AND 1005 AND lookUp(...)=0
GROUP BY user HAVING count(*) > 10
without the HAVING clause, query time is ok
which makes me think putting the fields in the lookup dimension table in the fact table will be better performance wise
even if it means much more duplicated data
at least with the type of queries i’ll like to perform
r
denormalising the table for the sake of a common query is usually a good idea
x
im curious what are the use cases of the lookup table
r
in any case, it would be good to see a profile of the slow query
x
btw, the google doc links in https://docs.google.com/document/d/1InWmxbRqwcqIakzvoEWHLxtX4XR9H5L01256EbAUHV8/edit# are locked to the public (am assuming they were meant to be open)
r
im curious what are the use cases of the lookup table
it's not always possible to denormalise, e.g. if the stream filling the lookup table can lag behind the stream populating the fact table. It may be the case that the reference data updates more frequently than the facts (e.g. fx rates vs transactions) and so on. If the lookup table is static, I would just denormalise and have fast queries.
yes, often perf issues like this can be resolved by configuration, but getting profiles for slow queries is generally useful because it helps discover and address "unknown unknowns" - there may be low hanging fruit here, and the profile will probably find it if it's there.
@Mayank or @Jackie might have some advice on tuning the HAVING clause later
x
thanks richard!
j
@xtrntr Does this query have small latency?
Copy code
SELECT user, count(*) FROM events 
WHERE time BETWEEN 0 AND 31 AND location BETWEEN 1000 AND 1005 AND lookUp(...)=0
GROUP BY user
Using
lookUp
within the filter is quite expensive because Pinot won't be able to utilize index to solve the query, but have to scan and lookup each value. The latency of this query with or without HAVING should be similar
FYI, if you have more than 10 users matching the filter, you should add an
ORDER BY count(*) DESC
to get the accurate result. Pinot won't keep all the groups by default in order to reduce the memory usage