Querying over two indexed properties is painfully slow when using ‘OR’. This query takes about 40 seconds to execute with 500 000 records in the bucket:
SELECT device FROM default
WHERE device.cashDrawerOpenCount > 1000000 OR
device.tempMaxBoard > 10000000
Execution time: 40s
Runnning separately is fine:
SELECT device FROM default
WHERE device.cashDrawerOpenCount > 1000000
Execution time: 4ms
SELECT device from default
WHERE device.tempMaxBoard < -100000
Execution time: 480ms
Both device.cashDrawerOpenCount and device.tempMaxBoard have global secondary indexes created.
This seems to be only relevant for Array type properties, which is not the case for either of the properties I am accessing. Is it relevant for this use case?
Thanks, that fixes the problem, although it will be kind of hard to translate from more complex conditions (multiple 'AND’s and 'OR’s). Does this happen specifically with ‘OR’ statements? Can we expect it to be fixed in some future release?
This issue only occurs with OR predicates involving unrelated predicates. So if you have a < 10 OR a > 20, N1QL will handle it well. If you have a < 10 OR b < 10, we currently go to a full primary scan, and you are better off using UNION. Yes, we will address this in the future. Currently, we tend to favor a single index.
@geraldss Is the unrelated predicates with OR is still an issue in 6.0 enterprise version
We are using
((a = 10) OR (a = 20 AND b in )
Currently we are overcoming it by UNION but
we need to order by and limit on large data on the UNION
SELECT a, d
FROM c
WHERE a = 10
UNION
SELECT a, d
FROM c
WHERE a = 20 AND b in
ORDER BY d
LIMIT 10 OFFSET 20000
does not push the limit and offset to the index, any suggestions? Thanks
LIMIT AND OFFSET can pushed to index only when all predicates are pushed to indexer and no false positives are possible and query order follows index order.
CREATE INDEX ix1 ON default(a,b);
SELECT a,d FROM default WHERE (a = 10) OR (a = 20 AND b IN [....]) ORDER BY d OFFSET 20000 LIMIt 10;
Also you can try this,
CREATE INDEX ix1 ON default(d,a,b);
SELECT a,d FROM default WHERE d IS NOT MISSING AND ((a = 10) OR (a = 20 AND b IN […])) ORDER BY d OFFSET 20000 LIMIt 10;
Hi,
Without UNION limit push down happens but the question is with UNION the limit on the result of the UNION the limit push down does not happen.
Thanks
Jothi
UNION requires eliminate duplicates and sometimes it is not possible to push limit/offset which can result in less rows (which contribute to wrong results). N1QL will disable optimizations in that situations.