Test du stockage en colonnes
Comme la plupart d'entre vous le savent probablement déjà, depuis environ la fin de l'année 2022, InterSystems IRIS a inclus la fonctionnalité de stockage en colonnes dans sa base de données. Dans l'article d'aujourd'hui, nous allons la mettre à l'épreuve en la comparant au stockage en lignes habituel.
Stockage en colonnes
Quelle est la principale caractéristique de ce type de stockage ? Eh bien, si l'on consulte la documentation officielle nous verrons ce fantastique tableau qui explique les principales caractéristiques des deux types de stockage (par lignes ou par colonnes) :
(ndt : je n'ai pas pu trduire le tableau ci-dessous car c'est une image)
.png)
Comme vous pouvez le constater, le stockage en colonnes est conçu principalement pour les tâches analytiques dans lesquelles des requêtes sont lancées sur des champs spécifiques de notre table, tandis que le stockage en lignes est plus optimal lorsqu'un grand nombre d'opérations d'insertion, de mise à jour et de suppression sont nécessaires, ainsi que pour l'obtention d'enregistrements complets.
Si vous continuez à lire la documentation, vous verrez à quel point il est simple de configurer notre table pour pouvoir utiliser le stockage en colonnes :
CREATETABLEtable (columntype, column2 type2, column3 type3) WITH STORAGETYPE = COLUMNAREn utilisant cette commande, nous définissons toutes les colonnes de notre tableau avec un stockage en colonnes, mais nous pouvons opter pour un modèle mixte dans lequel notre tableau dispose d'un stockage en lignes mais où certaines colonnes utilisent un stockage en colonnes.
Ce scénario mixte peut être intéressant dans les cas où les opérations d'agrégation telles que les sommes, les moyennes, etc. sont courantes. Dans ce cas, nous pourrions définir la colonne qui utilisera ce stockage :
CREATETABLEtable (columntype, column2 type2, column3 type3 WITH STORAGETYPE = COLUMNAR)Dans l'exemple précédent, nous avons défini une table avec un stockage en ligne et une colonne (column3) avec un stockage en colonne.
Comparatif
Pour comparer le temps passé par le stockage en colonnes et le stockage en lignes dans différentes requêtes, nous avons créé un petit exercice en utilisant Jupyter Notebook qui insérera une série d'enregistrements que nous générerons dans deux tables, la première avec un stockage en lignes ( Test.PurchaseOrderRow) et la seconde avec un stockage en colonnes dans deux de ses colonnes (Test.PurchaseOrderColumnar).
Test.PurchaseOrderRow
CREATETABLE Test.PurchaseOrderRow (
ReferenceINTEGER,
Customer VARCHAR(225),
PaymentDate DATE,
Vat NUMERIC(10,2),
Amount NUMERIC(10,2),
StatusVARCHAR(10))Test.PurchaseOrderColumnar
CREATETABLE Test.PurchaseOrderColumnar (
ReferenceINTEGER,
Customer VARCHAR(225),
PaymentDate DATE,
Vat NUMERIC(10,2),
Amount NUMERIC(10,2) WITH STORAGETYPE = COLUMNAR,
StatusVARCHAR(10) WITH STORAGETYPE = COLUMNAR)Si vous téléchargez le projet Open Exchange et le déployez dans votre Docker local, vous pouvez accéder à l'instance de Jupyter Notebook et examiner le fichier PerformanceTests.ipynb, qui sera responsable de la génération des données aléatoires que nous allons stocker en différentes phases dans nos tables et enfin il nous montrera un graphique avec la performance des opérations de requête.
Jetons un coup d'œil rapide à la configuration de notre projet :
docker-compose.yml
version:'3.7'services:# iris iris: init:true container_name:iris build: context:. dockerfile:iris/Dockerfile ports: -52774:52773 -51774:1972 volumes: -./shared:/shared environment: -ISC_DATA_DIRECTORY=/shared/durable command:--check-capsfalse--ISCAgentfalse# jupyter notebook jupyter: build: context:. dockerfile:jupyter/Dockerfile container_name:jupyter ports: -"8888:8888" environment: -JUPYTER_ENABLE_LAB=yes -JUPYTER_ALLOW_INSECURE_WRITES=true volumes: -./jupyter:/home/jovyan -./data:/app/data command:"start-notebook.sh --NotebookApp.token='' --NotebookApp.password=''"Nous déployons les conteneurs IRIS et Jupyter dans notre docker, en configurant initialement IRIS avec l'espace de noms "TEST" et les deux tables nécessaires au test.
Pour éviter de vous ennuyer avec du code, vous pouvez consulter le document PerformanceTests.ipynb à partir duquel nous nous connecterons à IRIS, générerons les enregistrements à insérer et les stockerons dans IRIS.
Exécution des tests
Les résultats ont été les suivants (en secondes) :
Inserts:
Les insertions effectuées sont de type "bulk" :
INSERTINTO Test.PurchaseOrderColumnar (Reference, Customer, PaymentDate, Vat, Amount, Status) VALUES (?, ?, ?, ?, ?, ?)Le temps nécessaire pour chaque lot d'insertions est le suivant :
|
Total inserts |
Row storage | Mixed storage |
| 1000 |
0.031733 |
0.041677 |
| 5000 |
0.159338 |
0.185252 |
| 20000 |
0.565775 |
0.642662 |
| 50000 |
1.486459 |
1.747124 |
| 100000 |
2.735016 |
3.265492 |
| 200000 |
5.395032 |
6.382278 |
Selects:
La fonction Select lancée comprend une fonction d'agrégation et une condition, toutes deux sur des colonnes avec stockage en colonnes :
SELECTAVG(Amount) FROM Test.PurchaseOrderColumnar WHEREStatus = 'SENT'|
Total rows |
Row storage | Mixed storage |
| 1000 |
0.002039 |
0.001178 |
| 5000 |
0.00328 |
0.000647 |
| 20000 |
0.005493 |
0.001555 |
| 50000 |
0.016616 |
0.000987 |
| 100000 |
0.036112 |
0.001605 |
| 200000 |
0.070909 |
0.002738 |
.png)
Conclusions
Comme vous pouvez le voir dans les résultats obtenus, l'opération est exactement ce qui est indiqué dans la documentation. L'inclusion de colonnes avec stockage en colonnes a légèrement pénalisé les performances lors de l'insertion (environ 18% plus lent pour notre exemple) alors que les requêtes sur ces mêmes colonnes ont considérablement amélioré le temps de réponse (258 fois plus rapide).
Il s'agit sans aucun doute d'un élément à prendre en compte lors de la planification du développement d'une application.
.png)