sql - MariaDB:如何在 WITH 语句中使用“INSERT ... SELECT”
问题描述
注意:这里涉及到 ColumnStore。
在工作中,我们有一个很大的 SQL 语句,它占用太多内存来在 prod 上执行。我目前正在努力减少查询消耗的大小。我尝试过使用不同的方法,但到目前为止,除了WITH ... AS (...)
出于某种原因之外,没有任何方法可以解决这个问题。但是,我需要将其与INSERT INTO ...
.
这是我试图开始工作的代码
TRUNCATE db1.myTable;
INSERT INTO db1.myTable(`all`, `needed`, `columns`)
(WITH everything AS (
SELECT all, needed, columns
FROM db1.mainTable T1
JOIN db1.secondTable T2
ON (T1.someCol = T2.someCol)
JOIN db2.thirdTable T3
ON (T1.anotherCol = T3.anotherCol)
LEFT JOIN db1.fourthTable T4
ON (T4.anotherCol = T1.anotherCol)
WHERE T2.yetAnotherCol >= (some_SELECT_subquery)
AND T1.valid = 1
) SELECT * FROM everything);
EXPLAIN (WITH everything AS ...
返回
+------+-------------+-----------------------+------+---------------+------+---------+------+------+-------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------------------+------+---------------+------+---------+------+------+-------------------------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 16000000000000 | |
| 2 | PRIMARY | T1 | ALL | NULL | NULL | NULL | NULL | 2000 | Using where with pushed condition |
| 2 | PRIMARY | T2 | ALL | NULL | NULL | NULL | NULL | 2000 | Using where; Using join buffer (flat, BNL join) |
| 2 | PRIMARY | T3 | ALL | NULL | NULL | NULL | NULL | 2000 | Using where; Using join buffer (flat, BNL join) |
| 2 | PRIMARY | T4 | ALL | NULL | NULL | NULL | NULL | 2000 | Using where |
| 3 | SUBQUERY | some_SELECT_subquery | ALL | NULL | NULL | NULL | NULL | 2000 | Using where with pushed condition |
+------+-------------+-----------------------+------+---------------+------+---------+------+------+-------------------------------------------------+
5 rows in set (0,21 sec)
如果我只使用WITH
-statement,我可以让它工作。如,我不使用INSERT INTO
. 完全没有问题,这样查询速度更快。我还尝试将查询分成几个WITH
s 进行快速测试,但因为我相信我弄乱了语法而放弃了。我对 SQL 不太擅长,对JOIN
s(初级开发人员)更是如此。
当我将WITH
-statement 与结合起来时INSER INTO ...
,MariaDB会以ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') SELECT * FROM everything)' at line 1
. 我还尝试在 之后添加分号... valid = 1
,合并最后两行,将开括号定位在... AS
新行之后,以及我能想到的其他一些可能与语法相关的问题。没运气。
我目前的想法是你不能INSERT INTO ... SELECT ...
与WITH ...
. 至少WITH
在开头没有 SELECT 应该在哪里。这是我可以从文档中收集到的。
所以,简而言之,我的问题是:我可以INSERT INTO ... SELECT
与WITH
-statement 结合吗?如果没有,我可以用另一种技术实现类似的效果吗?
还有其他方法可以提高查询的内存利用率吗?我不想弄乱 MariaDB 或 Docker 的配置选项,但如果这是唯一的可能性,我会考虑的。
解决方案
虽然我没有找到原始问题的答案,但我们决定通过减少子查询中收集的数据量来解决这个问题。我没有在原始问题中披露这一点,因为这不是我在发布问题时所知道的解决方案。我们将只从 Python 脚本中调用 SQL,我们可以在其中循环我们想要获取的周数。
WHERE T2.ID >= (SELECT ID - {week_number} FROM db1.secondTable WHERE NOW() BETWEEN monday AND sunday) AND T1.valid = 1);
推荐阅读
- excel - Excel JavaScript API 文件系统交互、系统调用和 API 调用?
- java - 时间选择器使我的应用程序崩溃并出现错误:E/libprocessgroup: failed to make and chown /acct/uid_10058: Read-only file system
- amazon-web-services - AWS Redshift DB 用户名验证约束是否发生了变化?
- php - 从调整后的复选框中获取数据到 codeigniter 控制器
- python - 如何从 kivy 屏幕收集数据,保存它们并将条形图绘制到输出可打印屏幕中
- neo4j - 节点属性显示不正确
- jquery - 使用来自输入的文件发送 Ajax 请求
- c# - 如何从 WPF 页面触发 KeyDown 事件
- linux - 从 Firefox 登录 Oracle express 18c 企业管理器失败
- r - 通过 R 使用保留字用 SQL 查询数据库