# Прочие виды запросов ## ATTACH Запрос полностью аналогичен запросу `CREATE`, но: - вместо слова `CREATE` используется слово `ATTACH`; - запрос не создаёт данные на диске, а предполагает, что данные уже лежат в соответствующих местах, и всего лишь добавляет информацию о таблице на сервер. После выполнения запроса `ATTACH` сервер будет знать о существовании таблицы. Если таблица перед этим была отсоединена (`DETACH`), т.е. её структура известна, можно использовать сокращенную форму записи без определения структуры. ```sql ATTACH TABLE [IF NOT EXISTS] [db.]name [ON CLUSTER cluster] ``` Этот запрос используется при старте сервера. Сервер хранит метаданные таблиц в виде файлов с запросами `ATTACH`, которые он просто исполняет при запуске (за исключением системных таблиц, которые явно создаются на сервере). ## CHECK TABLE Проверяет таблицу на повреждение данных. ```sql CHECK TABLE [db.]name ``` Запрос `CHECK TABLE` сравнивает текущие размеры файлов (в которых хранятся данные из колонок) с ожидаемыми значениями. Если значения не совпадают, данные в таблице считаются поврежденными. Искажение возможно, например, из-за сбоя при записи данных. Ответ содержит колонку `result`, содержащую одну строку с типом [Boolean](../data_types/boolean.md). Допустимые значения: - 0 - данные в таблице повреждены; - 1 - данные не повреждены. Запрос `CHECK TABLE` поддерживается только для следующих движков: - [Log](../operations/table_engines/log.md) - [TinyLog](../operations/table_engines/tinylog.md) - StripeLog В этих движках не предусмотрено автоматическое восстановление данных после сбоя. Поэтому используйте запрос `CHECK TABLE`, чтобы своевременно выявить повреждение данных. Обратите внимание, высокая защита целостности данных обеспечивается в таблицах семейства [MergeTree](../operations/table_engines/mergetree.md). Для избежания потери данных рекомендуется использовать именно эти таблицы. **Что делать, если данные повреждены** В этом случае можно скопировать оставшиеся неповрежденные данные в другую таблицу. Для этого: 1. Создайте новую таблицу с такой же структурой, как у поврежденной таблицы. Для этого выполните запрос `CREATE TABLE AS `. 2. Установите значение параметра [max_threads](../operations/settings/settings.md#settings-max_threads) в 1. Это нужно для того, чтобы выполнить следующий запрос в одном потоке. Установить значение параметра можно через запрос: `SET max_threads = 1`. 3. Выполните запрос `INSERT INTO SELECT * FROM `. В результате неповрежденные данные будут скопированы в другую таблицу. Обратите внимание, будут скопированы только те данные, которые следуют до поврежденного участка. 4. Перезапустите `clickhouse-client`, чтобы вернуть предыдущее значение параметра `max_threads`. ## DESCRIBE TABLE {#misc-describe-table} ```sql DESC|DESCRIBE TABLE [db.]table [INTO OUTFILE filename] [FORMAT format] ``` Возвращает описание столбцов таблицы. Результат запроса содержит столбцы (все столбцы имеют тип String): - `name` — имя столбца таблицы; - `type`— тип столбца; - `default_type` — в каком виде задано [выражение для значения по умолчанию](create.md#create-default-values): `DEFAULT`, `MATERIALIZED` или `ALIAS`. Столбец содержит пустую строку, если значение по умолчанию не задано. - `default_expression` — значение, заданное в секции `DEFAULT`; - `comment_expression` — комментарий к столбцу. Вложенные структуры данных выводятся в "развёрнутом" виде. То есть, каждый столбец - по отдельности, с именем через точку. ## DETACH Удаляет из сервера информацию о таблице name. Сервер перестаёт знать о существовании таблицы. ```sql DETACH TABLE [IF EXISTS] [db.]name [ON CLUSTER cluster] ``` Но ни данные, ни метаданные таблицы не удаляются. При следующем запуске сервера, сервер прочитает метаданные и снова узнает о таблице. Также, "отцепленную" таблицу можно прицепить заново запросом `ATTACH` (за исключением системных таблиц, для которых метаданные не хранятся). Запроса `DETACH DATABASE` нет. ## DROP Запрос имеет два вида: `DROP DATABASE` и `DROP TABLE`. ```sql DROP DATABASE [IF EXISTS] db [ON CLUSTER cluster] ``` Удаляет все таблицы внутри базы данных db, а затем саму базу данных db. Если указано `IF EXISTS` - не выдавать ошибку, если база данных не существует. ```sql DROP [TEMPORARY] TABLE [IF EXISTS] [db.]name [ON CLUSTER cluster] ``` Удаляет таблицу. Если указано `IF EXISTS` - не выдавать ошибку, если таблица не существует или база данных не существует. ## EXISTS ```sql EXISTS [TEMPORARY] TABLE [db.]name [INTO OUTFILE filename] [FORMAT format] ``` Возвращает один столбец типа `UInt8`, содержащий одно значение - `0`, если таблицы или БД не существует и `1`, если таблица в указанной БД существует. ## KILL QUERY ```sql KILL QUERY [ON CLUSTER cluster] WHERE [SYNC|ASYNC|TEST] [FORMAT format] ``` Пытается принудительно остановить исполняющиеся в данный момент запросы. Запросы для принудительной остановки выбираются из таблицы system.processes с помощью условия, указанного в секции `WHERE` запроса `KILL`. Примеры ```sql -- Принудительно останавливает все запросы с указанным query_id: KILL QUERY WHERE query_id='2-857d-4a57-9ee0-327da5d60a90' -- Синхронно останавливает все запросы пользователя 'username': KILL QUERY WHERE user='username' SYNC ``` Readonly-пользователи могут останавливать только свои запросы. По умолчанию используется асинхронный вариант запроса (`ASYNC`), который не дожидается подтверждения остановки запросов. Синхронный вариант (`SYNC`) ожидает остановки всех запросов и построчно выводит информацию о процессах по ходу их остановки. Ответ содержит колонку `kill_status`, которая может принимать следующие значения: 1. 'finished' - запрос был успешно остановлен; 2. 'waiting' - запросу отправлен сигнал завершения, ожидается его остановка; 3. остальные значения описывают причину невозможности остановки запроса. Тестовый вариант запроса (`TEST`) только проверяет права пользователя и выводит список запросов для остановки. ## KILL MUTATION {#kill-mutation} ```sql KILL MUTATION [ON CLUSTER cluster] WHERE [TEST] [FORMAT format] ``` Пытается остановить выполняющиеся в данные момент [мутации](alter.md#alter-mutations). Мутации для остановки выбираются из таблицы [`system.mutations`](../operations/system_tables.md#system_tables-mutations) с помощью условия, указанного в секции `WHERE` запроса `KILL`. Тестовый вариант запроса (`TEST`) только проверяет права пользователя и выводит список запросов для остановки. Примеры: ```sql -- Останавливает все мутации одной таблицы: KILL MUTATION WHERE database = 'default' AND table = 'table' -- Останавливает конкретную мутацию: KILL MUTATION WHERE database = 'default' AND table = 'table' AND mutation_id = 'mutation_3.txt' ``` Запрос полезен в случаях, когда мутация не может выполниться до конца (например, если функция в запросе мутации бросает исключение на данных таблицы). Данные, уже изменённые мутацией, остаются в таблице (отката на старую версию данных не происходит). ## OPTIMIZE {#misc_operations-optimize} ```sql OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition] [FINAL] ``` Просит движок таблицы сделать что-нибудь, что может привести к более оптимальной работе. Поддерживается только движками `*MergeTree`, в котором выполнение этого запроса инициирует внеочередное слияние кусков данных. Если указан `PARTITION`, то оптимизация будет производиться только для указаной партиции. Если указан `FINAL`, то оптимизация будет производиться даже когда все данные уже лежат в одном куске. !!! warning "Внимание"Запрос OPTIMIZE не может устранить причину появления ошибки "Too many parts". ## RENAME {#misc_operations-rename} Переименовывает одну или несколько таблиц. ```sql RENAME TABLE [db11.]name11 TO [db12.]name12, [db21.]name21 TO [db22.]name22, ... [ON CLUSTER cluster] ``` Все таблицы переименовываются под глобальной блокировкой. Переименовывание таблицы является лёгкой операцией. Если вы указали после TO другую базу данных, то таблица будет перенесена в эту базу данных. При этом, директории с базами данных должны быть расположены в одной файловой системе (иначе возвращается ошибка). ## SET ```sql SET param = value ``` Позволяет установить настройку `param` в значение `value`. Также можно одним запросом установить все настройки из заданного профиля настроек. Для этого укажите 'profile' в качестве имени настройки. Подробнее смотрите в разделе "Настройки". Настройка устанавливается на сессию, или на сервер (глобально), если указано `GLOBAL`. При установке глобальных настроек, эти настройки не применяются к уже запущенной сессии, включая текущую сессию. Она будет использована только для новых сессий. При перезапуске сервера теряются настройки, установленные с помощью `SET`. Установить настройки, которые переживут перезапуск сервера, можно только с помощью конфигурационного файла сервера. ## SHOW CREATE TABLE ```sql SHOW CREATE [TEMPORARY] TABLE [db.]table [INTO OUTFILE filename] [FORMAT format] ``` Возвращает один столбец statement типа `String`, содержащий одно значение - запрос `CREATE`, с помощью которого создана указанная таблица. ## SHOW DATABASES {#show-databases} ```sql SHOW DATABASES [INTO OUTFILE filename] [FORMAT format] ``` Выводит список всех баз данных. Запрос полностью аналогичен запросу `SELECT name FROM system.databases [INTO OUTFILE filename] [FORMAT format]`. Смотрите также раздел "Форматы". ## SHOW PROCESSLIST ```sql SHOW PROCESSLIST [INTO OUTFILE filename] [FORMAT format] ``` Выводит список запросов, выполняющихся в данный момент времени, кроме самих запросов `SHOW PROCESSLIST`. Выдаёт таблицу, содержащую столбцы: **user** - пользователь, под которым был задан запрос. Следует иметь ввиду, что при распределённой обработке запроса на удалённые серверы запросы отправляются под пользователем 'default'. И SHOW PROCESSLIST показывает имя пользователя для конкретного запроса, а не для запроса, который данный запрос инициировал. **address** - имя хоста, с которого был отправлен запрос. При распределённой обработке запроса на удалённых серверах — это имя хоста-инициатора запроса. Чтобы проследить, откуда был задан распределённый запрос изначально, следует смотреть SHOW PROCESSLIST на сервере-инициаторе запроса. **elapsed** - время выполнения запроса, в секундах. Запросы выводятся в порядке убывания времени выполнения. **rows_read**, **bytes_read** - сколько было прочитано строк, байт несжатых данных при обработке запроса. При распределённой обработке запроса суммируются данные со всех удалённых серверов. Именно эти данные используются для ограничений и квот. **memory_usage** - текущее потребление оперативки в байтах. Смотрите настройку 'max_memory_usage'. **query** - сам запрос. В запросах INSERT данные для вставки не выводятся. **query_id** - идентификатор запроса. Непустой, только если был явно задан пользователем. При распределённой обработке запроса идентификатор запроса не передаётся на удалённые серверы. Этот запрос аналогичен запросу `SELECT * FROM system.processes` за тем исключением, что последний отображает список запросов, включая самого себя. Полезный совет (выполните в консоли): ```bash watch -n1 "clickhouse-client --query='SHOW PROCESSLIST'" ``` ## SHOW TABLES ```sql SHOW [TEMPORARY] TABLES [FROM db] [LIKE 'pattern'] [INTO OUTFILE filename] [FORMAT format] ``` Выводит список таблиц: - из текущей базы данных или из базы db, если указано `FROM db`; - всех, или имя которых соответствует шаблону pattern, если указано `LIKE 'pattern'`; Запрос полностью аналогичен запросу: `SELECT name FROM system.tables WHERE database = 'db' [AND name LIKE 'pattern'] [INTO OUTFILE filename] [FORMAT format]`. Смотрите также раздел "Оператор LIKE". ## TRUNCATE ```sql TRUNCATE TABLE [IF EXISTS] [db.]name [ON CLUSTER cluster] ``` Удаляет все данные из таблицы. Если условие `IF EXISTS` не указано, запрос вернет ошибку, если таблицы не существует. Запрос `TRUNCATE` не поддерживается для следующих движков: [View](../operations/table_engines/view.md), [File](../operations/table_engines/file.md), [URL](../operations/table_engines/url.md) и [Null](../operations/table_engines/null.md). ## USE ```sql USE db ``` Позволяет установить текущую базу данных для сессии. Текущая база данных используется для поиска таблиц, если база данных не указана в запросе явно через точку перед именем таблицы. При использовании HTTP протокола запрос не может быть выполнен, так как понятия сессии не существует. [Оригинальная статья](https://clickhouse.yandex/docs/ru/query_language/misc/)