#couchbase #n1ql
#couchbase #n1ql
Вопрос:
Я столкнулся с странной проблемой в couchbase: я выполнял следующие два запроса:
SELECT *
FROM (
SELECT *
FROM (
SELECT *
FROM ssb_lineorder
LIMIT 10000) AS cte0
INNER JOIN ssb_ddate ON cte0.ssb_lineorder.lo_orderdate = ssb_ddate.d_datekey) AS cte1
JOIN ssb_part USE NL ON cte1.cte0.ssb_lineorder.lo_partkey = ssb_part.p_partkey
WHERE ssb_part.p_size > 10
и
SELECT *
FROM (
SELECT *
FROM (
SELECT *
FROM (
SELECT *
FROM ssb_lineorder
LIMIT 10000) AS cte0
INNER JOIN ssb_ddate ON cte0.ssb_lineorder.lo_orderdate = ssb_ddate.d_datekey) AS cte1
JOIN ssb_part USE NL ON cte1.cte0.ssb_lineorder.lo_partkey = ssb_part.p_partkey ) AS cte2
WHERE cte2.ssb_part.p_size > 10
Эти два точно такие же, за исключением последнего предложения WHERE . Согласно моим знаниям о реляционных СУБД, результаты должны быть точно такими же. но я получаю другой результат: 1 для первого запроса, 7972 для второго запроса.
Мне интересно, правильно ли я понял механизм n1ql?
Ответ №1:
Не должно быть никаких различий.
ОГРАНИЧЕНИЕ внутри без order by может привести к противоречивым результатам. 1 против 7972, это далеко.
Поскольку это зависит от данных, вам необходимо это отладить. Запустите пользовательский интерфейс и перейдите на вкладку Plan Text и посмотрите ItemsIn #, ItemsOut # каждого оператора и посмотрите, где что-то пошло не так.
Также добавьте предикат и уменьшите данные и посмотрите, что не так.
Поскольку ВНЕШНЕГО СОЕДИНЕНИЯ нет, попробуйте следующее.
CREATE INDEX ix1 ON ssb_part(p_size, p_partkey);
CREATE INDEX ix2 ON ssb_lineorder(lo_partkey, lo_orderdate);
CREATE INDEX ix3 ON ssb_ddate(d_datekey);
SELECT *
FROM ssb_part AS sp
JOIN ssb_lineorder AS sl ON sp.p_partkey = sl.lo_partkey
JOIN ssb_ddate AS sd ON sl.lo_orderdate = sd.d_datekey
WHERE sp.p_size > 10
SELECT *
FROM ssb_part AS sp
JOIN ssb_lineorder AS sl USE HASH (PROBE) ON sp.p_partkey = sl.lo_partkey
JOIN ssb_ddate AS sd USE HASH (PROBE) ON sl.lo_orderdate = sd.d_datekey
WHERE sp.p_size > 10 ;