> ## 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.

# Réécriture des requêtes PostgreSQL

> Partie 2 d’un guide sur la migration de PostgreSQL vers ClickHouse

> Voici la **Partie 2** d’un guide sur la migration de PostgreSQL vers ClickHouse. À l’aide d’un exemple concret, il montre comment mener efficacement la migration avec une approche de réplication en temps réel (CDC). Bon nombre des concepts abordés s’appliquent également aux transferts manuels de gros volumes de données de PostgreSQL vers ClickHouse.

La plupart des requêtes SQL de votre environnement PostgreSQL devraient s’exécuter dans ClickHouse sans modification, et probablement plus rapidement.

<div id="deduplication-cdc">
  ## Déduplication avec CDC
</div>

Lorsque vous utilisez la réplication en temps réel avec CDC, gardez à l’esprit que les mises à jour et les suppressions peuvent entraîner des lignes en double. Pour y remédier, vous pouvez utiliser des techniques reposant sur des vues et des vues matérialisées actualisables.

Consultez ce [guide](/fr/integrations/clickpipes/postgres/deduplication#query-like-with-postgres) pour découvrir comment migrer votre application de PostgreSQL vers ClickHouse le plus simplement possible à l’aide de la réplication en temps réel avec CDC.

<div id="optimize-queries-in-clickhouse">
  ## Optimiser les requêtes dans ClickHouse
</div>

Même s’il est possible d’effectuer cette migration avec un minimum de réécriture des requêtes, il est recommandé de tirer parti des fonctionnalités de ClickHouse pour simplifier considérablement les requêtes et améliorer encore leurs performances.

Les exemples ci-dessous couvrent des modèles de requêtes courants et montrent comment les optimiser avec ClickHouse. Ils utilisent l’intégralité du [Stack Overflow dataset](/fr/get-started/sample-datasets/stackoverflow) (jusqu’en avril 2024) sur des ressources équivalentes dans PostgreSQL et ClickHouse (8 cœurs, 32 GiB de RAM).

> Par souci de simplicité, les requêtes ci-dessous n’utilisent pas de techniques de déduplication des données.

> Les nombres indiqués ici différeront légèrement, car les données Postgres ne contiennent que les lignes qui respectent l’intégrité référentielle des clés étrangères. ClickHouse n’impose pas de telles contraintes et contient donc l’ensemble complet du dataset, par exemple avec les utilisateurs anonymes.

Utilisateurs (avec plus de 10 questions) qui reçoivent le plus de vues :

```sql theme={null}
-- ClickHouse
SELECT OwnerDisplayName, sum(ViewCount) AS total_views
FROM stackoverflow.posts
WHERE (PostTypeId = 'Question') AND (OwnerDisplayName != '')
GROUP BY OwnerDisplayName
HAVING count() > 10
ORDER BY total_views DESC
LIMIT 5
```

```response theme={null}
┌─OwnerDisplayName─┬─total_views─┐
│ Joan Venge       │    25520387 │
│ Ray Vega         │    21576470 │
│ anon             │    19814224 │
│ Tim              │    19028260 │
│ John             │    17638812 │
└──────────────────┴─────────────┘

5 rows in set. Elapsed: 0.360 sec. Processed 24.37 million rows, 140.45 MB (67.73 million rows/s., 390.38 MB/s.)
Peak memory usage: 510.71 MiB.
```

```sql theme={null}
--Postgres
SELECT OwnerDisplayName, SUM(ViewCount) AS total_views
FROM public.posts
WHERE (PostTypeId = 1) AND (OwnerDisplayName != '')
GROUP BY OwnerDisplayName
HAVING COUNT(*) > 10
ORDER BY total_views DESC
LIMIT 5;

        ownerdisplayname        | total_views
-------------------------+-------------
 Joan Venge             |       25520387
 Ray Vega               |       21576470
 Tim                    |       18283579
 J. Pablo Fern&#225;ndez |      12446818
 Matt                   |       12298764

Time: 107620.508 ms (01:47.621)
```

Quels `tags` ont le plus de `vues` :

```sql theme={null}
--ClickHouse
SELECT arrayJoin(arrayFilter(t -> (t != ''), splitByChar('|', Tags))) AS tags,
        sum(ViewCount) AS views
FROM posts
GROUP BY tags
ORDER BY views DESC
LIMIT 5
```

```response theme={null}
┌─tags───────┬──────views─┐
│ javascript │ 8190916894 │
│ python     │ 8175132834 │
│ java       │ 7258379211 │
│ c#         │ 5476932513 │
│ android    │ 4258320338 │
└────────────┴────────────┘

5 rows in set. Elapsed: 0.908 sec. Processed 59.82 million rows, 1.45 GB (65.87 million rows/s., 1.59 GB/s.)
```

```sql theme={null}
--Postgres
WITH tags_exploded AS (
        SELECT
        unnest(string_to_array(Tags, '|')) AS tag,
        ViewCount
        FROM public.posts
),
filtered_tags AS (
        SELECT
        tag,
        ViewCount
        FROM tags_exploded
        WHERE tag <> ''
)
SELECT tag AS tags,
        SUM(ViewCount) AS views
FROM filtered_tags
GROUP BY tag
ORDER BY views DESC
LIMIT 5;

        tags    |   views
------------+------------
 javascript | 7974880378
 python         | 7972340763
 java           | 7064073461
 c#             | 5308656277
 android        | 4186216900
(5 rows)

Time: 112508.083 ms (01:52.508)
```

**Fonctions d’agrégation**

Dans la mesure du possible, exploitez les fonctions d’agrégation de ClickHouse. Ci-dessous, nous montrons comment utiliser la fonction [argMax](/fr/reference/functions/aggregate-functions/argMax) pour calculer la question la plus consultée de chaque année.

```sql theme={null}
--ClickHouse
SELECT  toYear(CreationDate) AS Year,
        argMax(Title, ViewCount) AS MostViewedQuestionTitle,
        max(ViewCount) AS MaxViewCount
FROM stackoverflow.posts
WHERE PostTypeId = 'Question'
GROUP BY Year
ORDER BY Year ASC
FORMAT Vertical
```

```response theme={null}
Row 1:
──────
Year:                   2008
MostViewedQuestionTitle: How to find the index for a given item in a list?
MaxViewCount:           6316987

Row 2:
──────
Year:                   2009
MostViewedQuestionTitle: How do I undo the most recent local commits in Git?
MaxViewCount:           13962748

...

Row 16:
───────
Year:                   2023
MostViewedQuestionTitle: How do I solve "error: externally-managed-environment" every time I use pip 3?
MaxViewCount:           506822

Row 17:
───────
Year:                   2024
MostViewedQuestionTitle: Warning "Third-party cookie will be blocked. Learn more in the Issues tab"
MaxViewCount:           66975

17 rows in set. Elapsed: 0.677 sec. Processed 24.37 million rows, 1.86 GB (36.01 million rows/s., 2.75 GB/s.)
Peak memory usage: 554.31 MiB.
```

C’est nettement plus simple (et plus rapide) que la requête équivalente dans Postgres :

```sql theme={null}
--Postgres
WITH yearly_views AS (
        SELECT
        EXTRACT(YEAR FROM CreationDate) AS Year,
        Title,
        ViewCount,
        ROW_NUMBER() OVER (PARTITION BY EXTRACT(YEAR FROM CreationDate) ORDER BY ViewCount DESC) AS rn
        FROM public.posts
        WHERE PostTypeId = 1
)
SELECT
        Year,
        Title AS MostViewedQuestionTitle,
        ViewCount AS MaxViewCount
FROM yearly_views
WHERE rn = 1
ORDER BY Year;
 year |                                                 mostviewedquestiontitle                                                 | maxviewcount
------+-----------------------------------------------------------------------------------------------------------------------+--------------
 2008 | How to find the index for a given item in a list?                                                                       |       6316987
 2009 | How do I undo the most recent local commits in Git?                                                                     |       13962748

...

 2023 | How do I solve "error: externally-managed-environment" every time I use pip 3?                                          |       506822
 2024 | Warning "Third-party cookie will be blocked. Learn more in the Issues tab"                                              |       66975
(17 rows)

Time: 125822.015 ms (02:05.822)
```

**Expressions conditionnelles et tableaux**

Les fonctions conditionnelles et les fonctions sur les tableaux simplifient considérablement les requêtes. La requête suivante calcule les tags (avec plus de 10 000 occurrences) dont l’augmentation en pourcentage entre 2022 et 2023 est la plus forte. Remarquez à quel point la requête ClickHouse suivante est concise grâce aux expressions conditionnelles, aux fonctions sur les tableaux et à la possibilité de réutiliser des alias dans les clauses HAVING et SELECT.

```sql theme={null}
--ClickHouse
SELECT  arrayJoin(arrayFilter(t -> (t != ''), splitByChar('|', Tags))) AS tag,
        countIf(toYear(CreationDate) = 2023) AS count_2023,
        countIf(toYear(CreationDate) = 2022) AS count_2022,
        ((count_2023 - count_2022) / count_2022) * 100 AS percent_change
FROM stackoverflow.posts
WHERE toYear(CreationDate) IN (2022, 2023)
GROUP BY tag
HAVING (count_2022 > 10000) AND (count_2023 > 10000)
ORDER BY percent_change DESC
LIMIT 5
```

```response theme={null}
┌─tag─────────┬─count_2023─┬─count_2022─┬──────percent_change─┐
│ next.js     │      13788 │      10520 │   31.06463878326996 │
│ spring-boot │      16573 │      17721 │  -6.478189718413183 │
│ .net        │      11458 │      12968 │ -11.644046884639112 │
│ azure       │      11996 │      14049 │ -14.613139725247349 │
│ docker      │      13885 │      16877 │  -17.72826924216389 │
└─────────────┴────────────┴────────────┴─────────────────────┘

5 rows in set. Elapsed: 0.247 sec. Processed 5.08 million rows, 155.73 MB (20.58 million rows/s., 630.61 MB/s.)
Peak memory usage: 403.04 MiB.
```

```sql theme={null}
--Postgres
SELECT
        tag,
        SUM(CASE WHEN year = 2023 THEN count ELSE 0 END) AS count_2023,
        SUM(CASE WHEN year = 2022 THEN count ELSE 0 END) AS count_2022,
        ((SUM(CASE WHEN year = 2023 THEN count ELSE 0 END) - SUM(CASE WHEN year = 2022 THEN count ELSE 0 END))
        / SUM(CASE WHEN year = 2022 THEN count ELSE 0 END)::float) * 100 AS percent_change
FROM (
        SELECT
        unnest(string_to_array(Tags, '|')) AS tag,
        EXTRACT(YEAR FROM CreationDate) AS year,
        COUNT(*) AS count
        FROM public.posts
        WHERE EXTRACT(YEAR FROM CreationDate) IN (2022, 2023)
        AND Tags <> ''
        GROUP BY tag, year
) AS yearly_counts
GROUP BY tag
HAVING SUM(CASE WHEN year = 2022 THEN count ELSE 0 END) > 10000
   AND SUM(CASE WHEN year = 2023 THEN count ELSE 0 END) > 10000
ORDER BY percent_change DESC
LIMIT 5;

        tag     | count_2023 | count_2022 |   percent_change
-------------+------------+------------+---------------------
 next.js        |       13712 |         10370 |   32.22757955641273
 spring-boot |          16482 |         17474 |  -5.677005837243905
 .net           |       11376 |         12750 | -10.776470588235295
 azure          |       11938 |         13966 | -14.520979521695546
 docker         |       13832 |         16701 | -17.178612059158134
(5 rows)

Time: 116750.131 ms (01:56.750)
```

[Cliquez ici pour la 3e partie](/fr/get-started/migrate/postgres/migration-guide/migration-guide-part3)
