此文章来自官方文档,说明了,对于不支持pg 标准的sql 查询的变通方法,实际使用的时候有很大的指导意义

As Citus provides distributed functionality by extending PostgreSQL, it is compatible with PostgreSQL constructs. This means that users can use the tools and features that come with the rich and extensible PostgreSQL ecosystem for distributed tables created with Citus.

Citus supports all SQL queries on distributed tables, with only these exceptions:

Furthermore, in Multi-tenant Applications when queries are filtered by table Distribution Column to a single tenant then all SQL features work, including the ones above.

To learn more about PostgreSQL and its features, you can visit the PostgreSQL documentation.

For a detailed reference of the PostgreSQL SQL command dialect (which can be used as is by Citus users), you can see the SQL Command Reference.

Workarounds

Before attempting workarounds consider whether Citus is appropriate for your situation. Citus’ current version works well for real-time analytics and multi-tenant use cases.

Citus supports all SQL statements in the multi-tenant use-case. Even in the real-time analytics use-cases, with queries that span across nodes, Citus supports the majority of statements. The few types of unsupported queries are listed in Are there any PostgreSQL features not supported by Citus? Many of the unsupported features have workarounds; below are a number of the most useful.

JOIN a local and a distributed table

Attempting to execute a JOIN between a local table “local” and a distributed table “dist” causes an error:

SELECT * FROM local JOIN dist USING (id);

/*
ERROR: relation local is not distributed
STATEMENT: SELECT * FROM local JOIN dist USING (id);
ERROR: XX000: relation local is not distributed
LOCATION: DistributedTableCacheEntry, metadata_cache.c:711
*/

Although you can’t join such tables directly, by wrapping the local table in a subquery or CTE you can make Citus’ recursive query planner copy the local table data to worker nodes. By colocating the data this allows the query to proceed.

-- either

SELECT *
FROM (SELECT * FROM local) AS x
JOIN dist USING (id); -- or WITH x AS (SELECT * FROM local)
SELECT * FROM x
JOIN dist USING (id);

Remember that the coordinator will send the results in the subquery or CTE to all workers which require it for processing. Thus it’s best to either add the most specific filters and limits to the inner query as possible, or else aggregate the table. That reduces the network overhead which such a query can cause. More about this in Subquery/CTE Network Overhead.

INSERT…SELECT upserts lacking distribution column

Citus supports INSERT…SELECT…ON CONFLICT statements between co-located tables when the distribution column is among those columns selected and inserted. Also aggregates in the statement must include the distribution column in the GROUP BY clause. Failing to meet these conditions will raise an error:

ERROR: ON CONFLICT is not supported in INSERT ... SELECT via coordinator

If the upsert is an important operation in your application, the ideal solution is to model the data so that the source and destination tables are co-located, and so that the distribution column can be part of the GROUP BY clause in the upsert statement (if aggregating). However if this is not feasible then the workaround is to materialize the select query in a temporary distributed table, and upsert from there.

-- workaround for
-- INSERT INTO dest_table <query> ON CONFLICT <upsert clause> BEGIN;
CREATE UNLOGGED TABLE temp_table (LIKE dest_table);
SELECT create_distributed_table('temp_table', 'tenant_id');
INSERT INTO temp_table <query>;
INSERT INTO dest_table SELECT * FROM temp_table <upsert clause>;
DROP TABLE temp_table;
END;

Temp Tables: the Workaround of Last Resort

There are still a few queries that are unsupported even with the use of push-pull execution via subqueries. One of them is running window functions that partition by a non-distribution column.

Suppose we have a table called github_events, distributed by the column user_id. Then the following window function will not work:

-- this won't work

SELECT repo_id, org->'id' as org_id, count(*)
OVER (PARTITION BY repo_id) -- repo_id is not distribution column
FROM github_events
WHERE repo_id IN (8514, 15435, 19438, 21692);

There is another trick though. We can pull the relevant information to the coordinator as a temporary table:

-- grab the data, minus the aggregate, into a local table

CREATE TEMP TABLE results AS (
SELECT repo_id, org->'id' as org_id
FROM github_events
WHERE repo_id IN (8514, 15435, 19438, 21692)
); -- now run the aggregate locally SELECT repo_id, org_id, count(*)
OVER (PARTITION BY repo_id)
FROM results;

Creating a temporary table on the coordinator is a last resort. It is limited by the disk size and CPU of the node.

 
 
 
 

SQL Support and Workarounds的更多相关文章

  1. Stream Processing for Everyone with SQL and Apache Flink

    Where did we come from? With the 0.9.0-milestone1 release, Apache Flink added an API to process rela ...

  2. OGR SQL (GEOM)

    The OGRDataSource supports executing commands against a datasource via the OGRDataSource::ExecuteSQL ...

  3. OGR SQL

    The OGRDataSource supports executing commands against a datasource via the OGRDataSource::ExecuteSQL ...

  4. One SQL to Rule Them All – an Efficient and Syntactically Idiomatic Approach to Management of Streams and Tables(中英双语)

    文章标题 One SQL to Rule Them All – an Efficient and Syntactically Idiomatic Approach to Management of S ...

  5. About SQLite

    About SQLite See Also... Features When to use SQLite Frequently Asked Questions Well-known Users Boo ...

  6. GUID vs INT Debate【转】

    http://blogs.msdn.com/b/sqlserverfaq/archive/2010/05/27/guid-vs-int-debate.aspx I recently read a bl ...

  7. Dapper的完整扩展(转)

    真心想说:其实...我不想用Dapper,如果OrmLite.Net支持参数化的话,也就没Dapper的什么事情了,对于OrmLite.Net只能做后续跟踪...... 这个其实是看了Dapper作者 ...

  8. 推荐一个第三方Qt库的集合

    https://inqlude.org/ Stable libraries | Development versions | Unreleased | Commercial | All attica ...

  9. [20190416]11g下那些latch是Exclusive的.txt

    [20190416]11g下那些latch是Exclusive的.txt --//昨天测试了11g下那些latch是共享的,链接:--//是否反过来剩下的都是Exclusive的.继续测试: 1.环境 ...

随机推荐

  1. 为用户管理连接 Confluence 6 到 Jira 应用程序

    请注意,在使用这个功能的时候,你的 Jira 应用许可证数量和 Confluence 的许可证数量不需要完全等同.例如,你可以通过 Jira 管理一个 50 个用户的 Confluence 许可证,尽 ...

  2. python-day33--进程间通信(IPC)

    方式:队列(推荐使用) 一.基本情况 1.可以往队列里放任意类型的数据 2. 队列:先进先出 3. q=Queue(3) #可以设置队列中最多可以进入多少个值,也可以不设置 q.put('first' ...

  3. Leetcode 106

    /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...

  4. OAF 功能中的参数含义

    OA.jsp?OAFunc=POS_HT_SP_B_SUPP&OAPB=POS_SM_PRODUCT_BRANDING&OAHP=POS_SM_ADMIN_HOME&OASF= ...

  5. quartz---的Cron表达式

    quartz---的Cron表达式 CronTrigger CronTriggers往往比SimpleTrigger更有用,如果您需要基于日历的概念,而非SimpleTrigger完全指定的时间间隔, ...

  6. Centos7上部署openstack mitaka配置详解(将疑难点都进行划分)

    在配置openstack项目时很多人认为到处是坑,特别是新手,一旦进坑没有人指导,身体将会感觉一次次被掏空,作为菜鸟的我也感同身受,因为已经被掏空n次了. 以下也是我将整个openstack配置过程进 ...

  7. 【转】json与jsonp区别浅析(json才是目的,jsonp只是手段)

    一言以蔽之,json返回的是一串数据:而jsonp返回的是脚本代码(包含一个函数调用): JSON其实就是JavaScript中的一个对象,跟var obj={}在质上完全一样,只是在量上可以无限扩展 ...

  8. AOJ1024 Cleaning Robot 2.0

    先说一说这个OJ:貌似是11区某大学ACM的OJ,叫AIZU ONLINE JUDGE,貌似还可以看到部分犇的代码...跪跪跪 然后知道这个OJ是某场比赛安利的= = 接下来将做法: 首先我们可以发现 ...

  9. UVALive 4174

    DES:给出一个字符串.连续空格的个数代表一个新的字符.奇数个表示0.偶数个表示1.然后根据这个码作为ASCII码.写出对应的字符.就是统计空格个数.二进制转换成十进制的小模拟.但是比赛的时候敲得很不 ...

  10. SQL Server 调优系列玩转篇一(如何利用查询提示(Hint)引导语句运行)

    前言 前面几篇我们分析了关于SQL Server关于性能调优的一系列内容,我把它分为两个模块. 第一个模块注重基础内容的掌握,共分7篇文章完成,内容涵盖一系列基础运算算法,详细分析了如何查看执行计划. ...