> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-fbfa8bee.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Guia para usar e configurar o recurso de cache de consultas no ClickHouse

# Cache de consultas

O cache de consultas permite processar consultas `SELECT` apenas uma vez e atender às execuções subsequentes da mesma consulta diretamente do cache.
Dependendo do tipo de consulta, isso pode reduzir drasticamente a latência e o consumo de recursos do servidor ClickHouse.

<div id="background-design-and-limitations">
  ## Contexto, design e limitações
</div>

Os caches de consultas geralmente podem ser classificados como transacionalmente consistentes ou inconsistentes.

* Em caches transacionalmente consistentes, o banco de dados invalida (descarta) os resultados de consultas em cache se o resultado da consulta `SELECT` mudar
  ou puder mudar. No ClickHouse, as operações que alteram os dados incluem inserções/atualizações/exclusões em/de tabelas ou `merges`
  de colapsamento. O cache transacionalmente consistente é especialmente adequado para bancos de dados OLTP, como
  [MySQL](https://dev.mysql.com/doc/refman/5.6/en/query-cache.html) (que removeu o cache de consultas após a v8.0) e
  [Oracle](https://docs.oracle.com/database/121/TGDBA/tune_result_cache.htm).
* Em caches transacionalmente inconsistentes, pequenas imprecisões nos resultados das consultas são aceitas, partindo do pressuposto de que todas as entradas de cache recebem
  um período de validade após o qual expiram (por exemplo, 1 minuto) e de que os dados subjacentes mudam pouco durante esse período.
  Essa abordagem é, em geral, mais adequada para bancos de dados OLAP. Como exemplo de caso em que o cache transacionalmente inconsistente é suficiente,
  considere um relatório de vendas por hora em uma ferramenta de relatórios acessado simultaneamente por vários usuários. Em geral, os dados de vendas mudam
  devagar o suficiente para que o banco de dados precise computar o relatório apenas uma vez (representado pela primeira consulta `SELECT`). As consultas seguintes podem ser
  atendidas diretamente pelo cache de consultas. Neste exemplo, um período de validade razoável poderia ser de 30 min.

O cache transacionalmente inconsistente é tradicionalmente fornecido por ferramentas cliente ou pacotes de proxy (por exemplo,
[chproxy](https://www.chproxy.org/configuration/caching/)) que interagem com o banco de dados. Como resultado, a mesma lógica de cache e
configuração costuma ser duplicada. Com o cache de consultas do ClickHouse, a lógica de cache passa para o lado do servidor. Isso reduz o esforço
de manutenção e evita redundância.

<div id="configuration-settings-and-usage">
  ## Configurações e uso
</div>

<Note>
  No ClickHouse Cloud, você deve usar [configurações em nível de consulta](/pt-BR/concepts/features/configuration/settings/settings-query-level) para editar as configurações do cache de consultas. No momento, não há suporte para editar [configurações em nível de configuração](/pt-BR/concepts/features/configuration/server-config/configuration-files).
</Note>

<Note>
  O [clickhouse-local](/pt-BR/concepts/features/tools-and-utilities/clickhouse-local) executa uma única consulta por vez. Como o cache de resultados de consultas não faz sentido, o
  cache de resultados de consultas fica desativado no clickhouse-local.
</Note>

A configuração [use\_query\_cache](/pt-BR/reference/settings/session-settings#use_query_cache) pode ser usada para controlar se uma consulta específica ou todas as consultas da
sessão atual devem usar o cache de consultas. Por exemplo, a primeira execução da consulta

```sql theme={null}
SELECT some_expensive_calculation(column_1, column_2)
FROM table
SETTINGS use_query_cache = true;
```

armazenará o resultado da consulta no cache de consultas. Execuções subsequentes da mesma consulta (também com o parâmetro `use_query_cache = true`) irão
ler do cache o resultado já calculado e retorná-lo imediatamente.

<Note>
  Definir `use_query_cache` e todas as outras configurações relacionadas ao cache de consultas só tem efeito em instruções `SELECT` independentes. Em particular,
  os resultados de `SELECT`s em views criadas por `CREATE VIEW AS SELECT [...] SETTINGS use_query_cache = true` não são armazenados em cache, a menos que a instrução `SELECT`
  seja executada com `SETTINGS use_query_cache = true`.
</Note>

A forma como o cache é utilizado pode ser configurada em mais detalhes usando as configurações [enable\_writes\_to\_query\_cache](/pt-BR/reference/settings/session-settings#enable_writes_to_query_cache)
e [enable\_reads\_from\_query\_cache](/pt-BR/reference/settings/session-settings#enable_reads_from_query_cache) (ambas `true` por padrão). A primeira configuração
controla se os resultados das consultas são armazenados no cache, enquanto a segunda determina se o banco de dados deve tentar recuperar do cache os resultados das consultas.
Por exemplo, a consulta a seguir usará o cache apenas de forma passiva, ou seja, tentará ler dele, mas não armazenará nele o seu
resultado:

```sql theme={null}
SELECT some_expensive_calculation(column_1, column_2)
FROM table
SETTINGS use_query_cache = true, enable_writes_to_query_cache = false;
```

Para ter o máximo de controle, em geral recomenda-se fornecer as configurações `use_query_cache`, `enable_writes_to_query_cache` e
`enable_reads_from_query_cache` apenas em consultas específicas. Também é possível habilitar o cache no nível do usuário ou do perfil (por exemplo, via `SET
use_query_cache = true`), mas é preciso ter em mente que todas as consultas `SELECT` podem, nesse caso, retornar resultados em cache.

O cache de consultas pode ser limpo usando a instrução `SYSTEM CLEAR QUERY CACHE`. O conteúdo do cache de consultas é exibido na tabela de sistema
[system.query\_cache](/pt-BR/reference/system-tables/query_cache). O número de acertos e falhas do cache de consultas desde a inicialização do banco de dados é mostrado como eventos
"QueryCacheHits" e "QueryCacheMisses" na tabela de sistema [system.events](/pt-BR/reference/system-tables/events). Ambos os contadores são atualizados apenas para
consultas `SELECT` executadas com a configuração `use_query_cache = true`; outras consultas não afetam "QueryCacheMisses". O campo `query_cache_usage`
na tabela de sistema [system.query\_log](/pt-BR/reference/system-tables/query_log) mostra, para cada consulta executada, se o resultado da consulta foi gravado no
cache de consultas ou lido dele. As métricas `QueryCacheEntries` e `QueryCacheBytes` na tabela de sistema
[system.metrics](/pt-BR/reference/system-tables/metrics) mostram quantas entradas / bytes o cache de consultas contém no momento.

O cache de consultas existe uma vez por processo do servidor ClickHouse. No entanto, por padrão, os resultados em cache não são compartilhados entre usuários. Isso pode ser
alterado (veja abaixo), mas não é recomendado por motivos de segurança.

Os resultados das consultas são referenciados no cache de consultas pela [Abstract Syntax Tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree) de
cada consulta. Isso significa que o cache não diferencia maiúsculas de minúsculas; por exemplo, `SELECT 1` e `select 1` são tratados como a mesma consulta. Para
tornar a correspondência mais natural, todas as configurações no nível da consulta relacionadas ao cache de consultas e à [formatação de saída](/pt-BR/reference/settings/formats))
são removidas da AST.

Se a consulta foi interrompida devido a uma exceção ou a um cancelamento pelo usuário, nenhuma entrada é gravada no cache de consultas.

O tamanho do cache de consultas em bytes, o número máximo de entradas de cache e o tamanho máximo de entradas individuais de cache (em bytes e em
registros) podem ser configurados usando diferentes [opções de configuração do servidor](/pt-BR/reference/settings/server-settings/settings#query_cache).

```xml theme={null}
<query_cache>
    <max_size_in_bytes>1073741824</max_size_in_bytes>
    <max_entries>1024</max_entries>
    <max_entry_size_in_bytes>1048576</max_entry_size_in_bytes>
    <max_entry_size_in_rows>30000000</max_entry_size_in_rows>
</query_cache>
```

Também é possível limitar o uso do cache por usuários individuais usando [perfis de configurações](/pt-BR/concepts/features/configuration/settings/settings-profiles) e [restrições de
configurações](/pt-BR/concepts/features/configuration/settings/constraints-on-settings). Mais especificamente, você pode restringir a quantidade máxima de memória (em bytes) que um usuário pode
alocar no cache de consultas e o número máximo de resultados de consulta armazenados. Para isso, primeiro defina as configurações
[query\_cache\_max\_size\_in\_bytes](/pt-BR/reference/settings/session-settings#query_cache_max_size_in_bytes) e
[query\_cache\_max\_entries](/pt-BR/reference/settings/session-settings#query_cache_max_entries) em um perfil de usuário no `users.xml` e, em seguida, torne ambas as configurações
somente leitura:

```xml theme={null}
<profiles>
    <default>
        <!-- The maximum cache size in bytes for user/profile 'default' -->
        <query_cache_max_size_in_bytes>10000</query_cache_max_size_in_bytes>
        <!-- The maximum number of SELECT query results stored in the cache for user/profile 'default' -->
        <query_cache_max_entries>100</query_cache_max_entries>
        <!-- Make both settings read-only so the user cannot change them -->
        <constraints>
            <query_cache_max_size_in_bytes>
                <readonly/>
            </query_cache_max_size_in_bytes>
            <query_cache_max_entries>
                <readonly/>
            <query_cache_max_entries>
        </constraints>
    </default>
</profiles>
```

Para definir por quanto tempo, no mínimo, uma consulta deve ser executada para que seu resultado possa ser armazenado em cache, você pode usar a configuração
[query\_cache\_min\_query\_duration](/pt-BR/reference/settings/session-settings#query_cache_min_query_duration). Por exemplo, o resultado da consulta

```sql theme={null}
SELECT some_expensive_calculation(column_1, column_2)
FROM table
SETTINGS use_query_cache = true, query_cache_min_query_duration = 5000;
```

é armazenado em cache apenas se a consulta levar mais de 5 segundos para ser executada. Também é possível especificar quantas vezes uma consulta precisa ser executada até que seu resultado seja
armazenado em cache — para isso, use a configuração [query\_cache\_min\_query\_runs](/pt-BR/reference/settings/session-settings#query_cache_min_query_runs).

As entradas no cache de consultas ficam desatualizadas após um determinado período (time-to-live). Por padrão, esse período é de 60 segundos, mas um valor diferente
pode ser especificado no nível da sessão, do perfil ou da consulta usando a configuração [query\_cache\_ttl](/pt-BR/reference/settings/session-settings#query_cache_ttl). O cache de
consultas remove entradas de forma "preguiçosa", ou seja, quando uma entrada fica desatualizada, ela não é removida imediatamente do cache. Em vez disso, quando uma nova entrada
precisa ser inserida no cache de consultas, o banco de dados verifica se o cache tem espaço livre suficiente para a nova entrada. Se esse não for o
caso, o banco de dados tenta remover todas as entradas desatualizadas. Se o cache ainda não tiver espaço livre suficiente, a nova entrada não será inserida.

Se a consulta for executada via HTTP, o ClickHouse definirá os cabeçalhos `Age` e `Expires` com a idade (em segundos) e o timestamp de expiração da
entrada em cache.

As entradas no cache de consultas são comprimidas por padrão. Isso reduz o consumo geral de memória, ao custo de gravações mais lentas no cache e leituras mais lentas
a partir do cache de consultas. Para desabilitar a compressão, use a configuração [query\_cache\_compress\_entries](/pt-BR/reference/settings/session-settings#query_cache_compress_entries).

Às vezes, é útil manter em cache vários resultados da mesma consulta. Isso pode ser obtido usando a configuração
[query\_cache\_tag](/pt-BR/reference/settings/session-settings#query_cache_tag), que atua como um rótulo (ou espaço de nomes) para entradas do cache de consultas. O cache de consultas
considera como diferentes os resultados da mesma consulta com tags diferentes.

Exemplo de como criar três entradas diferentes no cache de consultas para a mesma consulta:

```sql theme={null}
SELECT 1 SETTINGS use_query_cache = true; -- query_cache_tag is implicitly '' (empty string)
SELECT 1 SETTINGS use_query_cache = true, query_cache_tag = 'tag 1';
SELECT 1 SETTINGS use_query_cache = true, query_cache_tag = 'tag 2';
```

Para remover apenas as entradas com a tag `tag` do cache de consultas, você pode usar a instrução `SYSTEM CLEAR QUERY CACHE TAG 'tag'`.

<div id="subquery-caching">
  ## Armazenamento em cache de subconsultas
</div>

Por padrão, `use_query_cache` na consulta externa não é propagado para as subconsultas. Isso significa que cada subconsulta deve habilitar explicitamente o armazenamento em cache:

```sql theme={null}
SELECT *
FROM (SELECT number FROM system.numbers LIMIT 1000 SETTINGS use_query_cache = true)
WHERE number > 500;
```

Neste exemplo, apenas o resultado da subconsulta interna é armazenado em cache. A consulta externa não é armazenada em cache.

Para habilitar o armazenamento em cache de todas as subconsultas de uma só vez, use a configuração `query_cache_for_subqueries`:

```sql theme={null}
SELECT *
FROM (SELECT number FROM system.numbers LIMIT 1000)
WHERE number > 500
SETTINGS use_query_cache = true, query_cache_for_subqueries = true;
```

Para desativar explicitamente o armazenamento em cache de uma subconsulta específica enquanto a propagação em massa estiver habilitada, defina `use_query_cache = false` nessa subconsulta:

```sql theme={null}
SELECT *
FROM (SELECT number FROM system.numbers LIMIT 1000 SETTINGS use_query_cache = false)
WHERE number > 500
SETTINGS use_query_cache = true, query_cache_for_subqueries = true;
```

As entradas de cache de subconsultas são visíveis em [system.query\_cache](/pt-BR/reference/system-tables/query_cache) com `is_subquery = 1`. A configuração `query_cache_ttl` também se aplica às entradas de cache de subconsultas e pode ser definida para cada subconsulta.

O ClickHouse lê os dados da tabela em blocos de [max\_block\_size](/pt-BR/reference/settings/session-settings#max_block_size) linhas. Devido à filtragem, agregação,
etc., os blocos de resultado normalmente são muito menores que 'max\_block\_size', mas também há casos em que são bem maiores. A configuração
[query\_cache\_squash\_partial\_results](/pt-BR/reference/settings/session-settings#query_cache_squash_partial_results) (habilitada por padrão) controla se os blocos de resultado
são combinados (se forem muito pequenos) ou divididos (se forem grandes) em blocos do tamanho de 'max\_block\_size' antes de serem inseridos no cache de resultados da consulta.
Isso reduz o desempenho das gravações no cache de consultas, mas melhora a taxa de compressão das entradas de cache e proporciona uma
granularidade de bloco mais natural quando os resultados da consulta são posteriormente servidos a partir do cache de consultas.

Como resultado, o cache de consultas armazena, para cada consulta, vários blocos de
resultado (parciais). Embora esse comportamento seja um bom padrão, ele pode ser suprimido usando a configuração
[query\_cache\_squash\_partial\_results](/pt-BR/reference/settings/session-settings#query_cache_squash_partial_results).

Além disso, os resultados de consultas com funções não determinísticas não são armazenados em cache por padrão. Essas funções incluem

* funções para acessar dicionários: [`dictGet()`](/pt-BR/reference/functions/regular-functions/ext-dict-functions) etc.
* [Funções Definidas pelo Usuário](/pt-BR/reference/statements/create/function) sem a tag `<deterministic>true</deterministic>` na definição
  XML,
* funções que retornam a data ou hora atual: [`now()`](/pt-BR/reference/functions/regular-functions/date-time-functions#now),
  [`today()`](/pt-BR/reference/functions/regular-functions/date-time-functions#today),
  [`yesterday()`](/pt-BR/reference/functions/regular-functions/date-time-functions#yesterday) etc.,
* funções que retornam valores aleatórios: [`randomString()`](/pt-BR/reference/functions/regular-functions/random-functions#randomString),
  [`fuzzBits()`](/pt-BR/reference/functions/regular-functions/random-functions#fuzzBits) etc.,
* funções cujo resultado depende do tamanho e da ordem, ou dos fragmentos internos usados no processamento de consultas:
  [`nowInBlock()`](/pt-BR/reference/functions/regular-functions/date-time-functions#nowInBlock) etc.,
  [`rowNumberInBlock()`](/pt-BR/reference/functions/regular-functions/other-functions#rowNumberInBlock),
  [`runningDifference()`](/pt-BR/reference/functions/regular-functions/other-functions#runningDifference),
  [`blockSize()`](/pt-BR/reference/functions/regular-functions/other-functions#blockSize) etc.,
* funções que dependem do ambiente: [`currentUser()`](/pt-BR/reference/functions/regular-functions/other-functions#currentUser),
  [`queryID()`](/pt-BR/reference/functions/regular-functions/other-functions#queryID),
  [`getMacro()`](/pt-BR/reference/functions/regular-functions/other-functions#getMacro) etc.

Para forçar o armazenamento em cache dos resultados de consultas com funções não determinísticas mesmo assim, use a configuração
[query\_cache\_nondeterministic\_function\_handling](/pt-BR/reference/settings/session-settings#query_cache_nondeterministic_function_handling).

Os resultados de consultas que envolvem tabelas de sistema (por exemplo, [system.processes](/pt-BR/reference/system-tables/processes)\` ou
[information\_schema.tables](/pt-BR/reference/system-tables/information_schema)) não são armazenados em cache por padrão. Para forçar o armazenamento em cache dos resultados de consultas com
tabelas de sistema mesmo assim, use a configuração [query\_cache\_system\_table\_handling](/pt-BR/reference/settings/session-settings#query_cache_system_table_handling).

Por fim, as entradas no cache de consultas não são compartilhadas entre usuários por motivos de segurança. Por exemplo, o usuário A não deve conseguir contornar uma
ROW POLICY em uma tabela executando a mesma consulta que outro usuário B para quem essa política não existe. No entanto, se necessário, as entradas de cache podem
ser marcadas como acessíveis a outros usuários (isto é, compartilhadas) informando a configuração
[query\_cache\_share\_between\_users](/pt-BR/reference/settings/session-settings#query_cache_share_between_users).

<div id="related-content">
  ## Conteúdo relacionado
</div>

* Blog: [Conheça o cache de consultas do ClickHouse](https://clickhouse.com/blog/introduction-to-the-clickhouse-query-cache-and-design)
