Экто присоединиться к ошибке "не равно" - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть две схемы, подобные этой:

schema "projects" do
  field :title, :string
  field :is_shared, :boolean
  timestamps()
end

schema "cards" do
  field :title, :string
  field :type, :string
  belongs_to(:project, Project)
end

Теперь я хочу найти карты проекта, которые не являются общими.

Я использую этот запрос:

    from(c0 in Card,
      join:
        p1 in subquery(
          from p0 in Project,
            where: p0.is_shared == false,
            select: p0.id
        ),
      on: c0.project_id != p1.id,
      where: c0.type == "golden"
    )

но это дает мне ошибку Postgrex:

Postgrex.Protocol (#PID<0.494.0>) disconnected: ** (DBConnection.ConnectionError) client #PID<0.527.0> timed out because it queued and checked out the connection for longer than 15000ms

Но когда я использую необработанный sql этот отладочный отпечаток, нет проблем.

SELECT c0."id",
       c0."title",
       c0."inserted_at",
       c0."updated_at"
FROM "cards" AS c0
         INNER JOIN (SELECT p0."id" AS "id" FROM "projects" AS p0 WHERE (p0."is_shared" = FALSE)) AS s1
                    ON c0."project_id" != s1."id"
WHERE (c0."type" = 'golden')

необработанный sql выше очень быстро. Это стоит всего 100-200 мс.

1 Ответ

1 голос
/ 30 апреля 2020

Как насчет попытки левого соединения и вставки нулевого идентификатора проекта для выполнения исключающего соединения, например:

from(c0 in Card,
left_join: p1 in Project,
on: c0.project_id ==  p1.id,
where: is_nil(p1.id) and c0.type == "golden" and p1.is_shared == false,
select: c0)

также вам не нужно ^ при работе со строкой == в экто.

Возможно, ваш запрос пытается объединить один идентификатор для каждого другого идентификатора, что означает, что если вы работаете с двумя таблицами по 10000 строк в каждой, вы получите почти 100 000 000 строк. Не уверен, почему этого не происходит на вашем sql.

Кроме того, если вы хотите «найти карты проекта, которые не были разделены», вы должны выполнить базовое c объединение, а не исключая один, как это:

from(c0 in Card,
join: p1 in Project,
on: c0.project_id == p1.id,
where: c0.type == "golden" and p1.is_shared == false,
select: c0)
...