首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在ecto中编写复杂的子查询作为from子句?

如何在ecto中编写复杂的子查询作为from子句?
EN

Stack Overflow用户
提问于 2018-01-19 16:12:57
回答 1查看 1.4K关注 0票数 1

我试图在subquery之后用Ecto语法编写,如何在FROM hierarchy,行之后编写子查询,它在from子句中,但我怀疑Ecto中是否可行?我想知道是否可以使用表联接甚至横向联接来执行这样的查询,而不会造成同样的性能损失?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT routes.id, routes.name
FROM routes
WHERE routes.id IN
  (SELECT DISTINCT hierarchy.parent
   FROM hierarchy,
    (SELECT DISTINCT unnest(segments.rels) AS rel
     FROM segments
     WHERE ST_Intersects(segments.geom, ST_SetSrid(ST_MakeBox2D(ST_GeomFromText('POINT(1866349.262143 6886808.978425)', -1), ST_GeomFromText('POINT(1883318.282423 6876413.542579)', -1)), 3857))) AS anon_1
   WHERE hierarchy.child = anon_1.rel)

我坚持了以下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hierarchy_subquery =
  Hierarchy
  |> distinct([h], h.parent)
Route
|> select([r], r.id, r.name)
|> where([r], r.id in subquery(hierarchy_subquery))

模式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
defmodule MyApp.Hierarchy do
  use MyApp.Schema

  schema "hierarchy" do
    field :parent, :integer
    field :child, :integer
    field :deph, :integer
  end
end
defmodule MyApp.Route do
  use MyApp.Schema

  schema "routes" do
    field :name, :string
    field :intnames, :map
    field :symbol, :string
    field :country, :string
    field :network, :string
    field :level, :integer
    field :top, :boolean
    field :geom, Geo.Geometry, srid: 3857
  end
end
defmodule MyApp.Segment do
  use MyApp.Schema

  schema "segments" do
    field :ways, {:array, :integer}
    field :nodes, {:array, :integer}
    field :rels, {:array, :integer}
    field :geom, Geo.LineString, srid: 3857
  end
end

我已经测试过各种查询的性能,下面的编辑是最快的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from r in Route,
        join: h in Hierarchy, on: r.id == h.parent,
        join: s in subquery(
          from s in Segment,
            distinct: true,
            where: fragment("ST_Intersects(?, ST_SetSrid(ST_MakeBox2D(ST_GeomFromText('POINT(1285982.015631 7217169.814674)', -1), ST_GeomFromText('POINT(2371999.313507 6454022.524275)', -1)), 3857))", s.geom),
            select: %{rel: fragment("unnest(?)", s.rels)}
        ),
        where: s.rel == h.child,
        select: {r.id, r.name}

结果:

计划时间:~0.605 ms执行时间:~37.232 ms

与上面的查询相同,但对于段子查询,joininner_lateral_join替换为:

计划时间:~1.353 ms执行时间:~38.518 ms

答复中的子查询:

计划时间:~1.017 ms执行时间:~41.288 ms

我以为inner_lateral_join会更快,但它不是。有人知道如何加速这个查询吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-20 03:40:02

以下是我要尝试的。我还没有证实它是否有效,但它应该指向正确的方向:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
segments =
  from s in Segment,
    where: fragment("ST_Intersects(?, ST_SetSrid(ST_MakeBox2D(ST_GeomFromText('POINT(1866349.262143 6886808.978425)', -1), ST_GeomFromText('POINT(1883318.282423 6876413.542579)', -1)), 3857)))", s.geom),
    distinct: true,
    select: %{rel: fragment("unnest(?)", s.rel)}

hierarchy =
  from h in Hierarchy,
    join: s in subquery(segments),
    where: h.child == s.rel,
    distinct: true,
    select: %{parent: h.parent}

routes =
  from r in Route,
    join: h in subquery(hierarchy),
    where: r.top and r.id == h.parent

要记住的事情:

  1. 从内部查询开始,然后转到外部查询
  2. 要访问子查询的结果,需要在子查询中选择一个映射。
  3. Ecto只允许子查询在from和join中。好消息是,您通常可以将"x IN subquery“重写为联接。
  4. 您可以尝试单独运行每个查询,并查看它们是否有效。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48351295

复制
相关文章
Ubuntu / Debian 安装 MySQL
首先打开网站 MySQL APT Repo,下载 MySQL APT 仓库描述文件:
Kindem
2022/08/12
2.7K0
Ubuntu / Debian 安装 MySQL
ubuntu最详细安装nginx_ubuntu centos debian
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/04
4910
开源社区的运作模式:Debian Vs. Ubuntu
Debian和Ubuntu都有一组官方授予的针对贡献者的成员角色,他们可以以参加选举或其他官方决策等方式参与到项目的治理中,同时这也是给贡献者分配工作的一种手段,大部分贡献者对他们获得的身份都感到很自豪。
Debian中国
2018/12/20
2K0
Ubuntu 20.04 Debian 9/10 开启Google BBR的方法
BBR是Google开源的TCP BBR拥塞控制算法,用于提升网络连接速度,提升空间巨大,优化效果非常明显;BBR仅支持4.9以上内核Ubuntu 18.04/20.04 CentOS 8 Debian 9/10均为4.9以上内核无需更换内核可以直接开启BBR。
Balliol Chen
2022/04/22
5.2K0
Ubuntu 20.04 Debian 9/10 开启Google BBR的方法
Debian 和Ubuntu Mono 3.0 部署包
Mono 3.0 刚发布,Debian 的Mono打包工作也开始了, 这篇博客《Mono 3.0 Preview Packages for Debian and Ubuntu 》讲述了Debian 和Ubuntu Mono 3.0 部署包的制作和最新的更新,目前最新的支持到Mono 3.0.6,目前还是在beta阶段,不用把它用于生产环境。 在/etc/apt/sources.list 文件里增加一行: deb http://debian.meebey.net/experimental/mono / 更新
张善友
2018/01/30
5600
Debian、Ubuntu系统中开机启动设置
Unix系统使用比较广泛的便是Linux系统,而基于Linux内核下也有很多衍生的其他的系统,其中就有Debian、Ubuntu这类的系统,在Linux系统下平时使用习惯的开机启动/etc/rc.local或/etc/rc.d/rc.local就没有了,那在Debian、Ubuntu下需要开启启动时就需要使用update-rc.d用来定义开机启动的命令 ,举一个简单的例子在Debian、Ubuntu开机启动iptables:
用户8710643
2021/06/11
1.1K0
Protobuf 扩展指南
另一个真实的例子,来自 google 的 http 扩展,这里插件会获取 名为 google.api.http 的 option,然后转换为 http 结构
王磊-字节跳动
2020/05/12
10.2K0
ubuntu强制修改密码_debian修改密码命令
-rwxr–r– 1 root root 2752 Dec 31 17:29 /etc/passwd
全栈程序员站长
2022/10/03
5.1K0
debian配置samba_ubuntu设置文件共享
●仅支持匿名用户的只读访问(请在该目录内存放一个文件名为file.txt, 文件内容为“Test File” 以便于测试)
全栈程序员站长
2022/09/29
8280
Debian和Ubuntu安装k8s
Xiongan-桃子
2023/10/23
2810
Debian7&Ubuntu 13.10下配置Bugzilla
Perl (5.8.1 or above) MySQL Apache2 Bugzilla
星哥玩云
2022/06/30
5850
在Debian和Ubuntu上使用Apache的SSL证书
本指南将向您展示如何在Debian和Ubuntu系统上启用SSL来确保通过Apache部署的网站的安全。原文地址
Noel
2018/09/03
2.1K0
Centos、ubuntu、debian安装docker-compose的正确方法
网上关于Centos7安装docker-compose的方法有2种,一种是通过python pip安装,但是我按照这种方法安装失败。第2种就是这里介绍的,直接从GitHub下载docker-compose编译好的可执行文件,该方法最为简单高效。牛哥强烈推荐centos7系统用户使用该方法安装docker-compose。
用户2135432
2023/10/21
9740
ubuntu下安装php扩展
参考原文地址:http://www.php.cn/php-weizijiaocheng-341528.html
lin_zone
2018/08/15
1.1K0
Debian、Ubuntu安装源配置文件说明
源列表主文件 /etc/apt/sources.list,兼取 /etc/apt/sources.list.d/*,结果以并集论。 源列表文件以行为单位,每行分多个字段,字段间以空白符分隔。井号(#)开头为注释行。样例如下:
Debian中国
2018/12/20
2.1K0
debian使用LVM扩展第二块硬盘
新入手一台2*2T机器,新装的系统挂载了第一块硬盘,通过查找资料摸索着挂载成功了第二块硬盘,这里仅作记录。 新系统的挂载情况: 新系统的分区挂载情况 fdisk -l查看磁盘信息:(其中/dev/sd
用户2135432
2018/06/04
2.1K0
如何在Ubuntu和Debian上安装R.
R是包含了数据可视化功能的用于统计分析的编程语言。该语言通过Comprehensive R Archive Network(CRAN)拥有高度的可扩展性,该网络托管了10,000多个R包,用于生成出版数据,专用计算工具等。
魔法少女伊莉雅
2018/09/04
1.9K0
如何在Debian和Ubuntu中安装VirtualBox 6
  VirtualBox是一款功能强大,通用且跨平台的完整虚拟化软件,主要面向服务器,桌面和嵌入式应用。它可以安装在任何操作系统(Linux,Windows,Mac等)上,并允许您在同一台计算机上安装和运行多个客户机操作系统。
会长君
2023/04/26
1.1K1
在Ubuntu 16.04或Debian 8上安装SquirrelMail
SquirrelMail是一个用PHP编写的webmail包,它支持SMTP和IMAP协议,并具有跨平台兼容性。SquirrelMail需要一台带有PHP的Web服务器才能正常运行。对于本指南,我们将使用Apache 2.如果您还没有安装Apache和PHP,可以在Ubuntu 16.04安装LAMP或Debian 8 安装LAMP查看我们的安装指南。
Likenttt
2018/09/12
2K0
在Ubuntu 16.04或Debian 8上安装SquirrelMail
Debian&Ubuntu下安装快捷ssh工具dropbear
注意:Debian&Ubintu通过apt安装后,会自动生成密钥等需要的信息,所以不用再手动配置。
子润先生
2021/06/14
1.4K0

相似问题

FTP上传后无法成功回调

13

FTP上传后未获得成功或错误回调

11

启动-停止-守护进程总是返回成功。

22

在alljoyn守护进程启动后无法启动服务

12

启动守护进程,但直到守护进程启动进程在golang中完成后才会继续。

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文