• Clickhouse分布式查询IN/JOIN与GLOABL IN GLOABL JOIN的区别


    • 当使用常规IN时,查询被发送到远程服务器,并且它们中的每个服务器都在运行子查询 IN JOIN 条款,除非每个远程服务器都存有全部数据,否则会造成数据不准确的情况
    • 使用 GLOBAL IN / GLOBAL JOINs,如select * from tablea where xx GLOABL in (select id from  tableb )这样的形式, 首先从所有的远程服务器中获得tableb关于ID的汇总,并将结果收集在临时表中。 然后将临时表发送到每个远程服务器,其中使用此临时数据运行查询。

    对于非分布式查询,请使用常规 IN / JOIN.
    在使用子查询时要小心 IN / JOIN 用于分布式查询处理的子句。让我们来看看一些例子。

    假设集群中的每个服务器都有一个正常的 local_table. 每个服务器还具有 distributed_table表与 分布 类型。

    对于查询 distributed_table,查询将被发送到所有远程服务器,并使用以下命令在其上运行 local_table.
    例如,查询

    SELECT uniq(UserID) FROM distributed_table

    将被发送到所有远程服务器

    SELECT uniq(UserID) FROM local_table

    并且并行运行它们中的每一个,直到达到可以结合中间结果的阶段。 然后将中间结果返回给请求者服务器并在其上合并,并
    将最终结果发送给客户端。


    现在让我们执行一个查询IN:

    SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM
    local_table WHERE CounterID = 34)

       计算两个网站的受众的交集。
    注意
    请记住,下面描述的算法可能会有不同的工作方式取决于 设置 distributed_product_mode 设置。
    此查询将以下列方式发送到所有远程服务器

    SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table
    WHERE CounterID = 34)

    换句话说,IN子句中的数据集将在每台服务器上独立收集,仅在每台服务器上本地存储的数据中收集。
    如果您已经为此情况做好准备,并且已经将数据分散到群集服务器上,以便单个用户Id的数据完全驻留在单个服务器上,则这
    将正常和最佳地工作。 在这种情况下,所有必要的数据将在每台服务器上本地提供。 否则,结果将是不准确的。 我们将查询
    的这种变体称为 “local IN”.


    若要更正数据在群集服务器上随机传播时查询的工作方式,可以指定 distributed_table 在子查询中。 查询如下所示:

    SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM
    distributed_table WHERE CounterID = 34)

    此查询将以下列方式发送到所有远程服务器

    SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM
    distributed_table WHERE CounterID = 34)

    子查询将开始在每个远程服务器上运行。 由于子查询使用分布式表,因此每个远程服务器上的子查询将重新发送到每个远程
    服务器

    SELECT UserID FROM local_table WHERE CounterID = 34

    例如,如果您有100台服务器的集群,则执行整个查询将需要10,000个基本请求,这通常被认为是不可接受的。
    在这种情况下,应始终使用GLOBAL IN而不是IN。 让我们来看看它是如何工作的查询

    SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID GLOBAL IN (SELECT UserID FROM
    distributed_table WHERE CounterID = 34)

    请求者服务器将运行子查询

    SELECT UserID FROM distributed_table WHERE CounterID = 34

    结果将被放在RAM中的临时表中。 然后请求将被发送到每个远程服务器

    SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID GLOBAL IN _data1

    和临时表 _data1 将通过查询发送到每个远程服务器(临时表的名称是实现定义的)。
    这比使用正常IN更优化。 但是,请记住以下几点:
    1. 创建临时表时,数据不是唯一的。 要减少通过网络传输的数据量,请在子查询中指定DISTINCT。 (你不需要为正常人
    做这个。)
    2. 临时表将被发送到所有远程服务器。 传输不考虑网络拓扑。 例如,如果10个远程服务器驻留在与请求者服务器非常远
    程的数据中心中,则数据将通过通道发送10次到远程数据中心。 使用GLOBAL IN时尽量避免使用大型数据集。
    3. 将数据传输到远程服务器时,无法配置网络带宽限制。 您可能会使网络过载。
    4. 尝试跨服务器分发数据,以便您不需要定期使用GLOBAL IN
    5. 如果您需要经常使用GLOBAL IN,请规划ClickHouse集群的位置,以便单个副本组驻留在不超过一个数据中心中,并
    且它们之间具有快速网络,以便可以完全在单个数据中心内处理查询。
    这也是有意义的,在指定一个本地表 GLOBAL IN 子句,以防此本地表仅在请求者服务器上可用,并且您希望在远程服务器上
    使用来自它的数据。

  • 相关阅读:
    java中Color类的简单总结
    java时间类简单总结
    Java集合类简单总结(重学)
    ES
    sql 获取表字段名称
    quartz定时器
    微信消息模板
    什么是.NET?什么是CLI?什么是CLR?IL是什么?JIT是什么,它是如何工作的?GC是什么,简述一下GC的工作方式?
    前端导出table表格
    c# 缓存 Cache
  • 原文地址:https://www.cnblogs.com/becoding/p/13431086.html
Copyright © 2020-2023  润新知