Примечание: это включает 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
заявление, я могу заставить его работать.Например, я не использую INSERT INTO
.Никаких проблем, и запрос еще быстрее.Я также провел быстрое тестирование, пытаясь разделить запрос на несколько WITH
с, но сдался, так как считаю, что перепутал синтаксис.Я не слишком хорошо разбираюсь в SQL, и тем более в JOIN
s (младший разработчик).
Когда я комбинирую WITH
утверждение с 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
заявлением?Если нет, могу ли я добиться чего-то похожего с другой техникой?
Есть ли другие способы улучшить использование памяти моего запроса?Я бы предпочел не связываться с параметрами конфигурации для MariaDB или Docker, но если это единственная возможность, я рассмотрю это.