{ "cells": [ { "cell_type": "markdown", "id": "7f1f5a4a-ae34-4a27-9efa-399edc0e384a", "metadata": { "tags": [] }, "source": [ "## Benchmark: ClickHouse Vs. InfluxDB Vs. Postgresql Vs. Parquet \n", "\n", "-----\n", "\n", "#### How to use:\n", "* Rename the file \"properties-model.ini\" to \"properties.ini\"\n", "* Fill with your own credentials\n", "----\n", "\n", "The proposal of this work is to compare the speed in read/writing a midle level of data ( a dataset with 9 columns and 50.000 lines) to four diferent databases:\n", "* ClickHouse\n", "* InfluxDB\n", "* Postgresql\n", "* Parquet (in a S3 Minio Storage)
\n", "ToDo:
\n", "* DuckDB with Polars\n", "* MongoDB\n", "* Kdb+\n", "\n", " \n", "Deve-se relevar:\n", "é uma \"cold-storage\" ou \"frezze-storage\"?
\n", "influxdb: alta leitura e possui a vantagem da indexaçõa para vizualização de dados em gráficos.\n", "\n", "notas: \n", "* comparar tamanho do csv com parquet" ] }, { "cell_type": "markdown", "id": "6bb26ce7-1e84-4665-accd-916bb977f95d", "metadata": { "tags": [] }, "source": [ "### Imports " ] }, { "cell_type": "code", "execution_count": 170, "id": "ab6c6c81-6ac1-4668-a79b-a9a0341fb35a", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 170, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import configparser\n", "import io\n", "import timeit\n", "from datetime import datetime\n", "\n", "import duckdb\n", "\n", "# from influxdb_client import InfluxDBClient\n", "import influxdb_client\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import pandas as pd\n", "import pdmongo as pdm\n", "from clickhouse_driver import Client\n", "from dotenv import load_dotenv\n", "\n", "# from influxdb_client.client.write_api import SYNCHRONOUS\n", "from minio import Minio\n", "from pymongo import MongoClient\n", "from pytz import timezone\n", "from qbstyles import mpl_style\n", "from qpython import qconnection\n", "from sqlalchemy import create_engine\n", "\n", "load_dotenv()" ] }, { "cell_type": "code", "execution_count": 89, "id": "55c3cd57-0996-4723-beb5-8f3196c96009", "metadata": { "tags": [] }, "outputs": [], "source": [ "# Variables\n", "dbname = \"EURUSDtest\"\n", "collection = \"finance\"" ] }, { "cell_type": "code", "execution_count": 50, "id": "968403e3-2e5e-4834-b969-be4600e2963a", "metadata": { "tags": [] }, "outputs": [], "source": [ "arq = configparser.RawConfigParser()\n", "arq.read(\"properties.ini\")\n", "ClickHouseUser = arq.get(\"CLICKHOUSE\", \"user\")\n", "ClickHouseKey = arq.get(\"CLICKHOUSE\", \"key\")\n", "ClickHouseUrl = arq.get(\"CLICKHOUSE\", \"url\")\n", "\n", "InfluxDBUser = arq.get(\"INFLUXDB\", \"user\")\n", "InfluxDBKey = arq.get(\"INFLUXDB\", \"key\")\n", "InfluxDBUrl = arq.get(\"INFLUXDB\", \"url\")\n", "InfluxDBBucket = arq.get(\"INFLUXDB\", \"bucket\")\n", "\n", "PostgresqlUser = arq.get(\"POSTGRESQL\", \"user\")\n", "PostgresqlKey = arq.get(\"POSTGRESQL\", \"key\")\n", "PostgresqlUrl = arq.get(\"POSTGRESQL\", \"url\")\n", "PostgresqlDB = arq.get(\"POSTGRESQL\", \"database\")\n", "\n", "S3MinioUser = arq.get(\"S3MINIO\", \"user\")\n", "S3MinioKey = arq.get(\"S3MINIO\", \"key\")\n", "S3MinioUrl = arq.get(\"S3MINIO\", \"url\")\n", "S3MinioRegion = arq.get(\"S3MINIO\", \"region\")\n", "\n", "MongoUser = arq.get(\"MONGODB\", \"user\")\n", "MongoKey = arq.get(\"MONGODB\", \"key\")\n", "MongoUrl = arq.get(\"MONGODB\", \"url\")" ] }, { "cell_type": "code", "execution_count": 51, "id": "3634a4ec-04c2-4f1e-8659-5d22eb17a254", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
idfromattoopencloseminmaxvolume
99999579847482023-03-03 18:13:3016778672250000000002023-03-03 18:13:451.0626951.0626351.0626301.06270064
99999679847492023-03-03 18:13:4516778672400000000002023-03-03 18:14:001.0626451.0626501.0626251.06265043
99999779847502023-03-03 18:14:0016778672550000000002023-03-03 18:14:151.0626401.0626251.0626201.06266547
99999879847512023-03-03 18:14:1516778672700000000002023-03-03 18:14:301.0626251.0625351.0625351.06264543
99999979847522023-03-03 18:14:3016778672850000000002023-03-03 18:14:451.0625351.0625201.0625201.06258059
\n", "
" ], "text/plain": [ " id from at \\\n", "999995 7984748 2023-03-03 18:13:30 1677867225000000000 \n", "999996 7984749 2023-03-03 18:13:45 1677867240000000000 \n", "999997 7984750 2023-03-03 18:14:00 1677867255000000000 \n", "999998 7984751 2023-03-03 18:14:15 1677867270000000000 \n", "999999 7984752 2023-03-03 18:14:30 1677867285000000000 \n", "\n", " to open close min max volume \n", "999995 2023-03-03 18:13:45 1.062695 1.062635 1.062630 1.062700 64 \n", "999996 2023-03-03 18:14:00 1.062645 1.062650 1.062625 1.062650 43 \n", "999997 2023-03-03 18:14:15 1.062640 1.062625 1.062620 1.062665 47 \n", "999998 2023-03-03 18:14:30 1.062625 1.062535 1.062535 1.062645 43 \n", "999999 2023-03-03 18:14:45 1.062535 1.062520 1.062520 1.062580 59 " ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# %%time\n", "# Load Dataset\n", "df = pd.read_csv(\"out.csv\", index_col=0)\n", "df.tail()" ] }, { "cell_type": "code", "execution_count": null, "id": "76199f91-31d6-416b-9f15-5d435b3792c9", "metadata": {}, "outputs": [], "source": [ "df[\"from\"] = pd.to_datetime(df[\"from\"], unit=\"s\")\n", "df[\"to\"] = pd.to_datetime(df[\"to\"], unit=\"s\")\n", "# Optional use when not transoformed yet\n", "# Transform Datetime" ] }, { "cell_type": "markdown", "id": "274cc026-2f48-4e38-b80f-b1a9ff982060", "metadata": { "tags": [] }, "source": [ "#### Funçoes\n", "\n", "-> Class" ] }, { "cell_type": "code", "execution_count": 5, "id": "27de1ec8-4de1-440a-b555-b4a46c5ef7ce", "metadata": {}, "outputs": [], "source": [ "def timestamp2dataHora(x, timezone_=\"America/Sao_Paulo\"):\n", " d = datetime.fromtimestamp(x, tz=timezone(timezone_))\n", " return d" ] }, { "cell_type": "markdown", "id": "4a8d5703-9bc9-4d38-83ff-457159304d58", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "### ClickHouse" ] }, { "cell_type": "code", "execution_count": 62, "id": "c3202bbb-2655-45b2-b166-9f45a3ef854c", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "'Database created'" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# !! driver tcp.\n", "def cHouseConnect():\n", " client = Client(\n", " host=ClickHouseUrl,\n", " user=ClickHouseUser,\n", " password=ClickHouseKey,\n", " settings={\"use_numpy\": True},\n", " )\n", " return client\n", "\n", "\n", "def cHouseDropTables(databasename):\n", " client = cHouseConnect()\n", " client.execute(\"DROP TABLE {}\".format(databasename))\n", " client.disconnect()\n", " return \"Database deleted\"\n", "\n", "\n", "# Create Tables in ClickHouse\n", "# !! ALTERAR TIPOS !!\n", "# ENGINE: 'Memory' desaparece quando server é reiniciado\n", "def cHouseCreateDb(databasename):\n", " client = cHouseConnect()\n", " client.execute(\n", " \"CREATE TABLE IF NOT EXISTS {} (id UInt32,\"\n", " \"from DateTime, at UInt64, to DateTime, open Float64,\"\n", " \"close Float64, min Float64, max Float64, volume UInt32)\"\n", " \"ENGINE MergeTree ORDER BY to\".format(databasename)\n", " )\n", " client.disconnect()\n", " return \"Database created\"\n", "\n", "\n", "# Write dataframe to db\n", "def cHouseInsertDf(dbName, dataframe):\n", " client = cHouseConnect()\n", " client.insert_dataframe(\"INSERT INTO {} VALUES\".format(dbName), dataframe)\n", " client.disconnect()\n", " return \" dataframe {} inserted in clickhouse database\".format(dataframe)\n", "\n", "\n", "def cHouseQueryDf(databaseName):\n", " client = cHouseConnect()\n", " dfQuery = client.query_dataframe(\"SELECT * FROM default.{}\".format(databaseName))\n", " client.disconnect()\n", " return dfQuery\n", "\n", "\n", "cHouseCreateDb(dbname)" ] }, { "cell_type": "code", "execution_count": 63, "id": "cc4865b3-a1bc-4a35-9624-15334754b3a1", "metadata": {}, "outputs": [], "source": [ "# Insert to db and benchmark time\n", "start = timeit.default_timer()\n", "cHouseInsertDf(dbname, df)\n", "stop = timeit.default_timer()\n", "cHouse_write_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 64, "id": "1fac82c1-2d04-44ef-893a-dc13b755e6d8", "metadata": {}, "outputs": [], "source": [ "# read from db and benchmark time\n", "start = timeit.default_timer()\n", "dfCh = cHouseQueryDf(dbname)\n", "stop = timeit.default_timer()\n", "cHouse_read_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 57, "id": "597ae7bd-2eea-44d7-b379-f0eb7e745c15", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
idfromattoopencloseminmaxvolume
199999580830542023-03-28 18:54:0016800296550032476672023-03-28 18:54:151.0840151.0840151.0839951.08404042
199999680830552023-03-28 18:54:1516800296700000000002023-03-28 18:54:301.0840201.0839501.0839401.08404555
199999780830552023-03-28 18:54:1516800296700000000002023-03-28 18:54:301.0840201.0839501.0839401.08404555
199999880830562023-03-28 18:54:3016800296850000000002023-03-28 18:54:451.0839651.0839551.0839451.08397540
199999980830562023-03-28 18:54:3016800296850000000002023-03-28 18:54:451.0839651.0839551.0839451.08397540
\n", "
" ], "text/plain": [ " id from at to \\\n", "1999995 8083054 2023-03-28 18:54:00 1680029655003247667 2023-03-28 18:54:15 \n", "1999996 8083055 2023-03-28 18:54:15 1680029670000000000 2023-03-28 18:54:30 \n", "1999997 8083055 2023-03-28 18:54:15 1680029670000000000 2023-03-28 18:54:30 \n", "1999998 8083056 2023-03-28 18:54:30 1680029685000000000 2023-03-28 18:54:45 \n", "1999999 8083056 2023-03-28 18:54:30 1680029685000000000 2023-03-28 18:54:45 \n", "\n", " open close min max volume \n", "1999995 1.084015 1.084015 1.083995 1.084040 42 \n", "1999996 1.084020 1.083950 1.083940 1.084045 55 \n", "1999997 1.084020 1.083950 1.083940 1.084045 55 \n", "1999998 1.083965 1.083955 1.083945 1.083975 40 \n", "1999999 1.083965 1.083955 1.083945 1.083975 40 " ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dfCh.tail()" ] }, { "cell_type": "code", "execution_count": 65, "id": "86794e47-611f-4ca8-a7e8-07e71afafe67", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7.571660671004793\n" ] } ], "source": [ "print(cHouse_read_execution_time)" ] }, { "cell_type": "code", "execution_count": 66, "id": "e7926062-8e84-4d3f-90a9-32807ce4f3d4", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5.804937635999522\n" ] } ], "source": [ "print(cHouse_write_execution_time)" ] }, { "cell_type": "code", "execution_count": 60, "id": "8faa5683-a204-461d-80c3-67644aa714ce", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "'Database deleted'" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Utils\n", "# %%time\n", "# dfCh = cHouseQueryDf(dbname)\n", "# drop table\n", "cHouseDropTables(dbname)" ] }, { "cell_type": "markdown", "id": "1d389546-911f-43f7-aad1-49f7bcc83503", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "### InfluxDB\n" ] }, { "cell_type": "code", "execution_count": 68, "id": "ecd217ab-0e16-40a6-9b92-9212b9bb20e9", "metadata": { "tags": [] }, "outputs": [], "source": [ "query = \"\"\"\n", "from(bucket: \"EURUSDtest\")\n", "|> range(start:2023-03-03T18:14:30Z, stop: now())\n", "|> filter(fn: (r) => r._measurement == \"id\")\n", "|> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")\"\"\"" ] }, { "cell_type": "code", "execution_count": 69, "id": "c3e7ebfd-76f1-4ac4-9833-312eb1a531af", "metadata": {}, "outputs": [], "source": [ "def influxdbConnect():\n", " client = influxdb_client.InfluxDBClient(\n", " url=InfluxDBUrl, token=InfluxDBKey, org=InfluxDBUser\n", " )\n", " return client\n", "\n", "\n", "def influxdbLoadCsv(csv=\"out.csv\", dictDates=[\"from\", \"to\"], index=\"from\"):\n", " # Read data from CSV without index and parse 'TimeStamp' as date.\n", " df = pd.read_csv(csv, sep=\",\", index_col=False, parse_dates=dictDates)\n", " # Set 'TimeStamp' field as index of dataframe # test another indexs\n", " df.set_index(index, inplace=True)\n", " return df\n", "\n", "\n", "def influxdbWriteCsv(dataFrame, bucket, measurement=\"id\", tag=\"volume\"):\n", " client = influxdbConnect()\n", " # write_options=SYNCHRONOUS\n", " with client.write_api() as writer:\n", " writer.write(\n", " bucket=bucket,\n", " record=dataFrame,\n", " data_frame_measurement_name=measurement,\n", " data_frame_tag_columns=[tag],\n", " )\n", " writer.__del__()\n", " client.__del__()\n", " return 0\n", "\n", "\n", "def influxdRead(org=InfluxDBUrl, query=query):\n", " client = influxdbConnect()\n", " InfluxDf = client.query_api().query_data_frame(org=\"librography\", query=query)\n", " # display(InfluxDf.head())\n", " return InfluxDf" ] }, { "cell_type": "code", "execution_count": 83, "id": "4be399bb-6b69-4f2b-aac0-9eab03cebfff", "metadata": { "tags": [] }, "outputs": [], "source": [ "def delete_data(measurement=\"id\", bucket=InfluxDBBucket, org=\"librography\"):\n", " client = influxdbConnect()\n", " delete_api = client.delete_api()\n", " start = \"1970-01-01T00:00:00Z\"\n", " stop = \"2024-10-30T00:00:00Z\"\n", " delete_api.delete(start, stop, f'_measurement=\"{measurement}\"', bucket, org)" ] }, { "cell_type": "code", "execution_count": null, "id": "baab1b7c-8f09-4d5e-8275-8588b4b5dd9d", "metadata": { "tags": [] }, "outputs": [], "source": [ "delete_data()" ] }, { "cell_type": "code", "execution_count": 70, "id": "e05266b8-ff32-462c-b059-325a40a53d25", "metadata": { "tags": [] }, "outputs": [], "source": [ "dafr = influxdbLoadCsv()\n", "# dafr.head()" ] }, { "cell_type": "code", "execution_count": 74, "id": "95191283-f11e-456f-8395-36981ab1ac51", "metadata": {}, "outputs": [], "source": [ "start = timeit.default_timer()\n", "influxdbWriteCsv(dafr, InfluxDBBucket)\n", "# dfIdw = cHouseQueryDf(dbname)\n", "stop = timeit.default_timer()\n", "influxdb_write_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 75, "id": "3e5bb029-4988-4692-bc5f-9a6f7fcc2159", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "87.55419652500132\n" ] } ], "source": [ "print(influxdb_write_execution_time)" ] }, { "cell_type": "code", "execution_count": 78, "id": "850c6921-5e1c-417a-bea6-ea18be642008", "metadata": { "tags": [] }, "outputs": [], "source": [ "# read from db and benchmark time\n", "start = timeit.default_timer()\n", "influxdRead()\n", "stop = timeit.default_timer()\n", "influxdb_read_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 79, "id": "3ee3c0dd-cb70-4124-a0fb-db8dd2c134c0", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "69.66793818100268\n" ] } ], "source": [ "print(influxdb_read_execution_time)" ] }, { "cell_type": "code", "execution_count": 80, "id": "54342a28-ba2b-4ade-a692-00566b53a639", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Write TimeRead TimeTotal Time
Click House5.80 sec7.57 sec13.38 sec
Kdb+2.87 sec4.15 sec7.03 sec
r2fill150
r3fill140
\n", "
" ], "text/plain": [ " Write Time Read Time Total Time\n", "Click House 5.80 sec 7.57 sec 13.38 sec\n", "Kdb+ 2.87 sec 4.15 sec 7.03 sec\n", "r2 fill 15 0\n", "r3 fill 14 0" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.tail()" ] }, { "cell_type": "markdown", "id": "b9ddfdc6-c899-4f6c-9b4e-8ec6ab6d7e05", "metadata": { "tags": [] }, "source": [ "### Postgresql" ] }, { "cell_type": "code", "execution_count": 91, "id": "16cd8eb7-333d-43fd-88e0-ee983645d3fd", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
idfromattoopencloseminmaxvolume
99999579847482023-03-03 18:13:3016778672250000000002023-03-03 18:13:451.0626951.0626351.0626301.06270064
99999679847492023-03-03 18:13:4516778672400000000002023-03-03 18:14:001.0626451.0626501.0626251.06265043
99999779847502023-03-03 18:14:0016778672550000000002023-03-03 18:14:151.0626401.0626251.0626201.06266547
99999879847512023-03-03 18:14:1516778672700000000002023-03-03 18:14:301.0626251.0625351.0625351.06264543
99999979847522023-03-03 18:14:3016778672850000000002023-03-03 18:14:451.0625351.0625201.0625201.06258059
\n", "
" ], "text/plain": [ " id from at \\\n", "999995 7984748 2023-03-03 18:13:30 1677867225000000000 \n", "999996 7984749 2023-03-03 18:13:45 1677867240000000000 \n", "999997 7984750 2023-03-03 18:14:00 1677867255000000000 \n", "999998 7984751 2023-03-03 18:14:15 1677867270000000000 \n", "999999 7984752 2023-03-03 18:14:30 1677867285000000000 \n", "\n", " to open close min max volume \n", "999995 2023-03-03 18:13:45 1.062695 1.062635 1.062630 1.062700 64 \n", "999996 2023-03-03 18:14:00 1.062645 1.062650 1.062625 1.062650 43 \n", "999997 2023-03-03 18:14:15 1.062640 1.062625 1.062620 1.062665 47 \n", "999998 2023-03-03 18:14:30 1.062625 1.062535 1.062535 1.062645 43 \n", "999999 2023-03-03 18:14:45 1.062535 1.062520 1.062520 1.062580 59 " ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Connect / Create Tables\n", "def psqlConnect():\n", " engine = create_engine(\n", " \"postgresql+psycopg2://{}:{}@{}:5432/{}\".format(\n", " PostgresqlUser, PostgresqlKey, PostgresqlUrl, PostgresqlDB\n", " )\n", " )\n", " return engine\n", "\n", "\n", "psqlConnect()\n", "# testar função\n", "df = pd.read_csv(\"out.csv\", index_col=0)\n", "df.tail()" ] }, { "cell_type": "code", "execution_count": 92, "id": "be31f3a0-b7ed-48e6-9b65-dc16319fb8d1", "metadata": {}, "outputs": [], "source": [ "# Drop old table and create new empty table\n", "def psqlCreateTables(databaseName):\n", " engine = psqlConnect()\n", " df.head(0).to_sql(databaseName, engine, if_exists=\"replace\", index=False)\n", " # Write\n", " conn = engine.raw_connection()\n", " cur = conn.cursor()\n", " output = io.StringIO()\n", " df.to_csv(output, sep=\"\\t\", header=False, index=False)\n", " output.seek(0)\n", " contents = output.getvalue()\n", " cur.copy_from(output, \"comparedbs\") # , null=\"\") # null values become ''\n", " conn.commit()\n", " cur.close()\n", " conn.close()\n", " # disconnect()\n", " return 0\n", "\n", "\n", "# funcao read sql\n", "def psqlReadTables():\n", " engine = psqlConnect()\n", " df = pd.read_sql_query('select * from \"comparedbs\"', con=engine)\n", " return df\n", "\n", "\n", "# testar função" ] }, { "cell_type": "code", "execution_count": 93, "id": "98cc9360-4b84-43e4-b23b-b32d0c50c3b9", "metadata": { "tags": [] }, "outputs": [], "source": [ "# Insert to db and benchmark time\n", "start = timeit.default_timer()\n", "psqlCreateTables(dbname)\n", "stop = timeit.default_timer()\n", "psql_write_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 97, "id": "75b7a130-92e3-4af1-9e1c-a285622c8996", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "32.67109364100179\n" ] } ], "source": [ "print(psql_write_execution_time)" ] }, { "cell_type": "code", "execution_count": 94, "id": "82e1b44e-35af-403f-9936-5e1561fd5abf", "metadata": { "tags": [] }, "outputs": [], "source": [ "start = timeit.default_timer()\n", "psqlReadTables()\n", "stop = timeit.default_timer()\n", "psql_read_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 95, "id": "6d1b7480-5bc7-4f08-8cf3-b9590802d8f7", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "146.20313464200444\n" ] } ], "source": [ "print(psql_read_execution_time)" ] }, { "cell_type": "code", "execution_count": 96, "id": "6acb2959-3255-43bd-aea5-9ef70acc8902", "metadata": { "tags": [] }, "outputs": [], "source": [ "# df.head()" ] }, { "cell_type": "markdown", "id": "f9e0393d-7d1d-406a-a068-9dbf4968e977", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "### S3 Parquet" ] }, { "cell_type": "code", "execution_count": 99, "id": "7c7022bf-9c3b-400a-9045-b089483f05ad", "metadata": { "tags": [] }, "outputs": [], "source": [ "# fazer sem funçao para ver se melhora\n", "# verifique se esta no ssd os arquivos da pasta git\n", "def s3Connect():\n", " client = Minio(\n", " S3MinioUrl,\n", " secure=False,\n", " region=S3MinioRegion,\n", " access_key=S3MinioUser,\n", " secret_key=S3MinioKey,\n", " )\n", " return client\n", "\n", "\n", "def s3CreateBucket(bucketName=\"data\"):\n", " client = s3Connect()\n", " found = client.bucket_exists(bucketName)\n", " if not found:\n", " return client.make_bucket(bucketName)\n", " else:\n", " return \"Bucket '{}' already exists\".format(bucketName)\n", "\n", "\n", "def s3uploadCsv():\n", " client = s3Connect()\n", " client.fput_object(\n", " \"data\",\n", " \"data.parquet\",\n", " \"data/data.parquet\",\n", " )\n", " return (\n", " \"'data/data.parquet' is successfully uploaded as \"\n", " \"object 'data.parquet' to bucket 'data'.\"\n", " )" ] }, { "cell_type": "code", "execution_count": 100, "id": "cd7fe012-9eee-4f91-8c07-8e0148633766", "metadata": { "tags": [] }, "outputs": [], "source": [ "# Insert to db and benchmark time\n", "df.to_parquet(\"data/data.parquet\")\n", "s3CreateBucket()\n", "start = timeit.default_timer()\n", "s3uploadCsv()\n", "stop = timeit.default_timer()\n", "s3_write_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": null, "id": "a803e870-1970-496f-b678-a7f8866870cf", "metadata": {}, "outputs": [], "source": [ "# falta read (parquet to df)" ] }, { "cell_type": "code", "execution_count": 101, "id": "390918c8-c88f-404a-96c4-685d578fdad0", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4.160801975995128\n" ] } ], "source": [ "print(s3_write_execution_time)" ] }, { "cell_type": "code", "execution_count": 102, "id": "666d4bc7-933d-4e6e-87c1-72fd37e61e0d", "metadata": { "tags": [] }, "outputs": [], "source": [ "start = timeit.default_timer()\n", "pq = pd.read_parquet(\"data/data.parquet\", engine=\"pyarrow\")\n", "stop = timeit.default_timer()\n", "s3_read_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 106, "id": "573b10c3-5dfe-420a-a988-688d4ebcde24", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
idfromattoopencloseminmaxvolume
077308012023-01-02 15:58:4516726751400000000002023-01-02 15:59:001.0659951.0660351.0659301.06607057
177308022023-01-02 15:59:0016726751550000000002023-01-02 15:59:151.0660551.0660851.0660051.06611552
277308032023-01-02 15:59:1516726751700000000002023-01-02 15:59:301.0660801.0660251.0660251.06611057
377308042023-01-02 15:59:3016726751850000000002023-01-02 15:59:451.0659801.0659851.0658851.06604564
477308052023-01-02 15:59:4516726752000000000002023-01-02 16:00:001.0659751.0660551.0658301.06605550
\n", "
" ], "text/plain": [ " id from at to \\\n", "0 7730801 2023-01-02 15:58:45 1672675140000000000 2023-01-02 15:59:00 \n", "1 7730802 2023-01-02 15:59:00 1672675155000000000 2023-01-02 15:59:15 \n", "2 7730803 2023-01-02 15:59:15 1672675170000000000 2023-01-02 15:59:30 \n", "3 7730804 2023-01-02 15:59:30 1672675185000000000 2023-01-02 15:59:45 \n", "4 7730805 2023-01-02 15:59:45 1672675200000000000 2023-01-02 16:00:00 \n", "\n", " open close min max volume \n", "0 1.065995 1.066035 1.065930 1.066070 57 \n", "1 1.066055 1.066085 1.066005 1.066115 52 \n", "2 1.066080 1.066025 1.066025 1.066110 57 \n", "3 1.065980 1.065985 1.065885 1.066045 64 \n", "4 1.065975 1.066055 1.065830 1.066055 50 " ] }, "execution_count": 106, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pq.head()" ] }, { "cell_type": "code", "execution_count": 103, "id": "fefb54f6-9040-4fd7-9861-20322c202d92", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.5090432809956837\n" ] } ], "source": [ "print(s3_read_execution_time)" ] }, { "cell_type": "markdown", "id": "50d1fc58-89a7-4507-aff0-6e943656cfe0", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "### MongoDB" ] }, { "cell_type": "code", "execution_count": 107, "id": "d104d9af-fa34-4261-8478-329a28ee4f2e", "metadata": { "tags": [] }, "outputs": [], "source": [ "port = \"27017\"\n", "\n", "\n", "def mongoLoadCsv(csvfile):\n", " data = pd.read_csv(\"out.csv\")\n", " return data\n", "\n", "\n", "def mongoConnect():\n", " client = MongoClient(\n", " \"mongodb://{}:{}@{}/EURUSDtest?retryWrites=true&w=majority\".format(\n", " MongoUser, MongoKey, MongoUrl\n", " ),\n", " authSource=\"admin\",\n", " )\n", " return client\n", "\n", "\n", "def mongoWriteDict(dados, dbs, collection):\n", " client = mongoConnect()\n", " db = client[dbs]\n", " collection = db[collection]\n", " # data.reset_index(inplace=True)\n", " data_dict = dados.to_dict(\"records\")\n", " # return data_dict\n", " collection.insert_many(data_dict)\n", " return 0\n", "\n", "\n", "def mongoRead():\n", " df = pdm.read_mongo(\n", " collection, [], \"mongodb://192.168.1.162:27017/{}\".format(dbname)\n", " )\n", " return df" ] }, { "cell_type": "code", "execution_count": 108, "id": "739de6aa-313f-4ccd-96c8-fa22d0cc687e", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Unnamed: 0idfromattoopencloseminmaxvolume
0077308012023-01-02 15:58:4516726751400000000002023-01-02 15:59:001.0659951.0660351.0659301.06607057
1177308022023-01-02 15:59:0016726751550000000002023-01-02 15:59:151.0660551.0660851.0660051.06611552
2277308032023-01-02 15:59:1516726751700000000002023-01-02 15:59:301.0660801.0660251.0660251.06611057
3377308042023-01-02 15:59:3016726751850000000002023-01-02 15:59:451.0659801.0659851.0658851.06604564
4477308052023-01-02 15:59:4516726752000000000002023-01-02 16:00:001.0659751.0660551.0658301.06605550
\n", "
" ], "text/plain": [ " Unnamed: 0 id from at \\\n", "0 0 7730801 2023-01-02 15:58:45 1672675140000000000 \n", "1 1 7730802 2023-01-02 15:59:00 1672675155000000000 \n", "2 2 7730803 2023-01-02 15:59:15 1672675170000000000 \n", "3 3 7730804 2023-01-02 15:59:30 1672675185000000000 \n", "4 4 7730805 2023-01-02 15:59:45 1672675200000000000 \n", "\n", " to open close min max volume \n", "0 2023-01-02 15:59:00 1.065995 1.066035 1.065930 1.066070 57 \n", "1 2023-01-02 15:59:15 1.066055 1.066085 1.066005 1.066115 52 \n", "2 2023-01-02 15:59:30 1.066080 1.066025 1.066025 1.066110 57 \n", "3 2023-01-02 15:59:45 1.065980 1.065985 1.065885 1.066045 64 \n", "4 2023-01-02 16:00:00 1.065975 1.066055 1.065830 1.066055 50 " ] }, "execution_count": 108, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = mongoLoadCsv(\"out.csv\")\n", "data.head()" ] }, { "cell_type": "code", "execution_count": 109, "id": "0af8f72c-5b58-4dfc-af36-c5b4bc79f127", "metadata": { "tags": [] }, "outputs": [], "source": [ "start = timeit.default_timer()\n", "dfCh = mongoWriteDict(data, dbname, \"finance\")\n", "stop = timeit.default_timer()\n", "mongo_write_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 110, "id": "0757f14c-4677-41d3-90d8-63b884e24e7e", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "54.566006569999445\n" ] } ], "source": [ "print(mongo_write_execution_time)" ] }, { "cell_type": "code", "execution_count": 111, "id": "e7922312-74cb-4df3-8dea-e5ee0d99fab7", "metadata": { "tags": [] }, "outputs": [], "source": [ "start = timeit.default_timer()\n", "dfMongo = mongoRead()\n", "stop = timeit.default_timer()\n", "mongo_read_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 112, "id": "93fb22ea-b283-4447-b774-fe755a782223", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "34.66374846499821\n" ] } ], "source": [ "print(mongo_read_execution_time)" ] }, { "cell_type": "markdown", "id": "97405e42-61dc-42c7-8220-237a312c0ec7", "metadata": { "tags": [] }, "source": [ "### DuckDB" ] }, { "cell_type": "code", "execution_count": 119, "id": "bbcdb883-d6dc-46db-88db-4c90b84522ba", "metadata": {}, "outputs": [], "source": [ "# https://duckdb.org/2022/07/27/art-storage.html\n", "\n", "\n", "def duckdbConnect():\n", " cursor = duckdb.connect()\n", " return cursor\n", "\n", "\n", "def duckdbLoadCsv(csvFile=\"out.csv\"):\n", " data = pd.read_csv(csvFile)\n", " return data\n", "\n", "\n", "# write\n", "def duckdbWrite(file, dataframe, tableName):\n", " conn = duckdbConnect()\n", " conn = duckdb.connect(file)\n", " # conn.execute(\"DROP TABLE EURUSDtest\")\n", " # conn.sql('CREATE TABLE EURUSDtest(i INTEGER)')\n", " conn.register(\"tempTable\", dataframe)\n", " conn.execute(\"CREATE TABLE {} AS SELECT * FROM tempTable\".format(tableName))\n", " conn.close()\n", " return 0\n", "\n", "\n", "def duckdbRead(dbfile):\n", " conn = duckdbConnect()\n", " conn = duckdb.connect(dbfile)\n", " conn.execute(\"SELECT * FROM {}\".format(dbname)).fetchdf()\n", " conn.close()\n", " return 0" ] }, { "cell_type": "code", "execution_count": 120, "id": "1c787f48-5640-4eb5-9456-be8f0a8211eb", "metadata": { "tags": [] }, "outputs": [], "source": [ "data = duckdbLoadCsv()" ] }, { "cell_type": "code", "execution_count": 117, "id": "f07f03d0-021e-4dc3-bfa8-efc029a9797a", "metadata": { "tags": [] }, "outputs": [ { "ename": "CatalogException", "evalue": "Catalog Error: Table with name EURUSD does not exist!\nDid you mean \"temp.information_schema.tables\"?", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mCatalogException\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[117], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m conn \u001b[38;5;241m=\u001b[39m duckdbConnect()\n\u001b[0;32m----> 2\u001b[0m \u001b[43mconn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mDROP TABLE EURUSD\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n", "\u001b[0;31mCatalogException\u001b[0m: Catalog Error: Table with name EURUSD does not exist!\nDid you mean \"temp.information_schema.tables\"?" ] } ], "source": [ "conn = duckdbConnect()\n", "conn.execute(\"DROP TABLE EURUSDtest\")" ] }, { "cell_type": "code", "execution_count": 74, "id": "45620be8-34c6-4a3a-89f7-09337f665c90", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "conn.register(\"EURUSDtest\", data)" ] }, { "cell_type": "code", "execution_count": 84, "id": "9eb19431-fbad-43b4-84f7-0043e65de162", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
name
0EURUSDtest
\n", "
" ], "text/plain": [ " name\n", "0 EURUSDtest" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "conn = duckdb.connect(\"file.db\")\n", "# conn.execute(\"DROP TABLE EURUSDtest\")\n", "# conn.sql(\"CREATE TABLE EURUSDtest(i INTEGER)\")\n", "display(conn.execute(\"SHOW TABLES\").df())" ] }, { "cell_type": "code", "execution_count": null, "id": "32037939-def0-48e7-9a47-46bcf1a5883c", "metadata": { "tags": [] }, "outputs": [], "source": [ "# conn = duckdbConnect()\n", "conn.execute(\"SELECT * FROM EURUSDtest\")\n", "conn.fetchall()" ] }, { "cell_type": "code", "execution_count": 121, "id": "c6f53d67-684b-4b34-a573-472986ee3e47", "metadata": { "tags": [] }, "outputs": [], "source": [ "start = timeit.default_timer()\n", "dfDuckdb = duckdbWrite(\"file.db\", data, dbname)\n", "stop = timeit.default_timer()\n", "duckdb_write_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 122, "id": "102f363a-b35d-433c-8752-7acc85c27bdc", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.02947735300404\n" ] } ], "source": [ "print(duckdb_write_execution_time)" ] }, { "cell_type": "code", "execution_count": 123, "id": "f630fc1a-0d52-4e3a-9dfe-1ec60d188033", "metadata": { "tags": [] }, "outputs": [], "source": [ "start = timeit.default_timer()\n", "dfDuckdb = duckdbRead(\"file.db\")\n", "stop = timeit.default_timer()\n", "duckdb_read_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 124, "id": "c6abdaaa-3ac2-425b-9208-d6cb79afe966", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.5635835029970622\n" ] } ], "source": [ "print(duckdb_read_execution_time)" ] }, { "cell_type": "markdown", "id": "4409cc89-ed14-4313-ac89-65b826038533", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "### Kdb+" ] }, { "cell_type": "code", "execution_count": 31, "id": "14f63810-1943-4e28-9bce-2148be6be02d", "metadata": {}, "outputs": [], "source": [ "# numpy version boolean fix\n", "np.bool = np.bool_" ] }, { "cell_type": "code", "execution_count": 25, "id": "bbd217e3-695f-4fa6-ae42-83db1dde8311", "metadata": {}, "outputs": [], "source": [ "# functions\n", "# cd ~ && q/l64/q -p 5001\n", "\n", "\n", "def kdbConnect():\n", " q = qconnection.QConnection(host=\"localhost\", port=5001)\n", " q.open()\n", " return q\n", "\n", "\n", "def kdbLoadCsv(file=\"out.csv\"):\n", " data = pd.read_csv(file)\n", " return data\n", "\n", "\n", "def kdbWrite():\n", " q = kdbConnect()\n", " data = kdbLoadCsv()\n", " q.sendSync(\"{t::x}\", data)\n", " q.sendSync(\"`:/home/sandman/q/tab1 set t\")\n", " q.close()\n", " return 0\n", "\n", "\n", "def kdbRead():\n", " q = kdbConnect()\n", " # df2 = q.sendSync(\"tab2: get `:/home/sandman/q/tab1\")\n", " # df2 = q.sendSync(\"tab2\")\n", " df = pd.DataFrame(q(\"t\")) # , pandas=True))\n", " # df3 = q.sendSync(\"select from t\")\n", " # ver todos esses loads\n", " q.close()\n", " return 0" ] }, { "cell_type": "code", "execution_count": 28, "id": "67f0c26e-44fb-40b0-a147-5d97bfbbded2", "metadata": {}, "outputs": [], "source": [ "# write\n", "start = timeit.default_timer()\n", "dfKdb = kdbWrite()\n", "stop = timeit.default_timer()\n", "kdb_write_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": 29, "id": "dcb200be-ffc9-4bcc-8554-5740fb420ab5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.8739770100000896\n" ] } ], "source": [ "# print write time\n", "print(kdb_write_execution_time)" ] }, { "cell_type": "code", "execution_count": 30, "id": "d4ce0203-b0c7-440b-a3ca-d7b2a7682474", "metadata": {}, "outputs": [], "source": [ "# read\n", "start = timeit.default_timer()\n", "dfKdb = kdbRead()\n", "stop = timeit.default_timer()\n", "kdb_read_execution_time = stop - start" ] }, { "cell_type": "code", "execution_count": null, "id": "1a16fd76-2158-40fe-9285-c53791f8ed51", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4.153738381999574\n" ] } ], "source": [ "# print read time\n", "print(kdb_read_execution_time)" ] }, { "cell_type": "markdown", "id": "7c923c16-d741-4903-8493-81ff3c4d300e", "metadata": { "tags": [] }, "source": [ "## Table" ] }, { "cell_type": "code", "execution_count": 125, "id": "3a09558c-73e6-4324-9fc5-782fcd0d12e5", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Write TimeRead TimeTotal Time
Click House5.80 sec7.57 sec13.38 sec
InfluxDb87.55 sec69.67 sec157.22 sec
Postgresql32.67 sec146.20 sec178.87 sec
S34.16 sec0.51 sec4.67 sec
MongoDb54.57 sec34.66 sec89.23 sec
DuckDb2.03 sec0.56 sec2.59 sec
Kdb+2.87 sec4.15 sec7.03 sec
\n", "
" ], "text/plain": [ " Write Time Read Time Total Time\n", "Click House 5.80 sec 7.57 sec 13.38 sec\n", "InfluxDb 87.55 sec 69.67 sec 157.22 sec\n", "Postgresql 32.67 sec 146.20 sec 178.87 sec\n", "S3 4.16 sec 0.51 sec 4.67 sec\n", "MongoDb 54.57 sec 34.66 sec 89.23 sec\n", "DuckDb 2.03 sec 0.56 sec 2.59 sec\n", "Kdb+ 2.87 sec 4.15 sec 7.03 sec" ] }, "execution_count": 125, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# duckdb_write_execution_time\n", "s = \" sec\"\n", "data = [\n", " [\n", " \"{:.2f}\".format(cHouse_write_execution_time) + s,\n", " \"{:.2f}\".format(cHouse_read_execution_time) + s,\n", " \"{:.2f}\".format(cHouse_write_execution_time + cHouse_read_execution_time) + s,\n", " ],\n", " [\n", " \"{:.2f}\".format(influxdb_write_execution_time) + s,\n", " \"{:.2f}\".format(influxdb_read_execution_time) + s,\n", " \"{:.2f}\".format(influxdb_write_execution_time + influxdb_read_execution_time)\n", " + s,\n", " ],\n", " [\n", " \"{:.2f}\".format(psql_write_execution_time) + s,\n", " \"{:.2f}\".format(psql_read_execution_time) + s,\n", " \"{:.2f}\".format(psql_write_execution_time + psql_read_execution_time) + s,\n", " ],\n", " [\n", " \"{:.2f}\".format(s3_write_execution_time) + s,\n", " \"{:.2f}\".format(s3_read_execution_time) + s,\n", " \"{:.2f}\".format(s3_write_execution_time + s3_read_execution_time) + s,\n", " ],\n", " [\n", " \"{:.2f}\".format(mongo_write_execution_time) + s,\n", " \"{:.2f}\".format(mongo_read_execution_time) + s,\n", " \"{:.2f}\".format(mongo_write_execution_time + mongo_read_execution_time) + s,\n", " ],\n", " [\n", " \"{:.2f}\".format(duckdb_write_execution_time) + s,\n", " \"{:.2f}\".format(duckdb_read_execution_time) + s,\n", " \"{:.2f}\".format(duckdb_write_execution_time + duckdb_read_execution_time) + s,\n", " ],\n", " [\n", " \"{:.2f}\".format(kdb_write_execution_time) + s,\n", " \"{:.2f}\".format(kdb_read_execution_time) + s,\n", " \"{:.2f}\".format(kdb_write_execution_time + kdb_read_execution_time) + s,\n", " ],\n", "]\n", "\n", "index_labels = [\n", " \"Click House\",\n", " \"InfluxDb\",\n", " \"Postgresql\",\n", " \"S3\",\n", " \"MongoDb\",\n", " \"DuckDb\",\n", " \"Kdb+\",\n", "]\n", "dff = pd.DataFrame(\n", " data, columns=[\"Write Time\", \"Read Time\", \"Total Time\"], index=index_labels\n", ")\n", "dff" ] }, { "cell_type": "markdown", "id": "7baf1fd1-2afd-41b5-a579-33f053e4ddfc", "metadata": {}, "source": [ "## Graph\n" ] }, { "cell_type": "code", "execution_count": 199, "id": "a9740731-6077-4bf1-bb65-b4c4225ac79b", "metadata": { "tags": [] }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def plot(dark):\n", " mpl_style(dark)\n", " # plt.subplots(figsize=(16, 8))\n", " plt.figure().set_figwidth(14)\n", " x = np.arange(7) # change here\n", " width = 0.40\n", " y1 = [\n", " cHouse_read_execution_time,\n", " influxdb_read_execution_time,\n", " psql_read_execution_time,\n", " s3_read_execution_time,\n", " mongo_read_execution_time,\n", " duckdb_read_execution_time,\n", " kdb_read_execution_time,\n", " ] # change here\n", " y2 = [\n", " cHouse_write_execution_time,\n", " influxdb_write_execution_time,\n", " psql_write_execution_time,\n", " s3_write_execution_time,\n", " mongo_write_execution_time,\n", " duckdb_write_execution_time,\n", " kdb_write_execution_time,\n", " ] # change here\n", " plt.bar(x - 0.2, y2, width)\n", " plt.bar(x + 0.2, y1, width)\n", " plt.xticks(\n", " x,\n", " [\n", " \"Click House\",\n", " \"InfluxDb\",\n", " \"Postgresql\",\n", " \"S3 Parquet\",\n", " \"MongoDb\",\n", " \"DuckDb\",\n", " \"Kdb+\",\n", " ],\n", " )\n", " plt.xlabel(\"Databases\")\n", " plt.ylabel(\"Seconds\")\n", " plt.legend([\"Write\", \"Read\"]) # ver\n", " plt.rcParams.update({\"font.size\": 18})\n", " plt.show()\n", "\n", "\n", "plot(dark=True)" ] }, { "cell_type": "markdown", "id": "aeda3a71-f57d-419d-98b4-b711ea2e61af", "metadata": {}, "source": [ "## Graph (bests)" ] }, { "cell_type": "code", "execution_count": 200, "id": "810e8a81-0a20-40aa-bb07-7bb71094b8d2", "metadata": { "tags": [] }, "outputs": [ { "data": { "image/png": "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FHW/8PySuWd0Ok1ZUyboqv599c3n6frk3YNn3157RX9N/SJD//3qS90xeJDGfPi++vXsIenQl2plTZmgMzqdVvJ9WWvH8NuTFHPaqbr71kT9/O1kvfPy80f62wegEq1as1aPPPOC9u3bpxuvufKQl3P+879/SeraOUap772trCkT9P34sRoUe90h931V/7766rNUtWrZotRrHo9Hcxcs1L2PPqWY6Cid2/XMktdcpqknHry35OeSi847t5KOFoCTok/tqFEjX9WHn36mUZ+kSZJqREbqpScfVdaUCRqf9pFioqNKbdewfn2NevNV/TR1ska/O1InntDyeEcHjhiXgiLotWzeTM2aNNa3mdNtbR8eHqb3X39ZUzOna8TTz6u42KNOp3YsNa9b17P0+P3DNOKZ5zV3wULbefte1l03XnOl7rhvhNb9tUF3Dh6kkS88rWtuTpJlWYfd9uwuZ6hn94t1feJt2rZ9hxo3aqjQatUkSed2PVPDbh+iex5+QkuXr9BF552rkS8+owGxCdq1e4/tvECw27lrt9b8uV5PPXSfvpw8RX8sXnLIwn7QDddqcHysqoeHa+fu3Xrzg+QK7b9GZKT6XtZdi5ctlyQtW7lKaWPHaefu3br0wvP17CMPKnfJMm3YtEmSFFG9utq1bq2B8TdLkrqc3kl3DB6kOx94WLlLlykpIU6tW7Wq8PEdbu14/d0P1L5dWy4FBfyIZVn670+/qGvnM7R67brDzj25bRu9/txTeuz5lzXjp19UPTz8kB9ybx0Ur0vO76ab7xqmrdu2l7m/DZs2afGy5eocfZp+nvW7JOmcM7voxZFv65lX3lC3rmfq5ace01U3DfbLS9sBVEyXmE66ddBNemnkO5oyLbNk/IGht6tGZIT6XhunsLBQjXzhmVLbDujbS0MffLTkZ5I3nn9aA+NuLvdzDuAkzlhD0KtTu7YkacthfhA8nPPP7qri4mK9k/yRCgoKVVxcrDkLsn3m9OvVQw8PH6o77h9Rbql215BblDVlgs/XP/Xp0V2fjZuoFavX6MCBA3o7+SM1athQp3ZoX27WoqJihYWGqs2JreRyubRp8xatW/+XJOnaAf30yWefa8my5fJ6vZr+409as+5Pdet61hH+jgD4t8Sh92rZilVKSojT15+latwnKeraOcZnzscZY3Vuz3668qbBGjfpa23fkXfY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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def plot(dark):\n", " mpl_style(dark)\n", " plt.figure().set_figwidth(15, 10)\n", " x = np.arange(4) # change here\n", " width = 0.40\n", " y1 = [\n", " cHouse_read_execution_time,\n", " s3_read_execution_time,\n", " duckdb_read_execution_time,\n", " kdb_read_execution_time,\n", " ] # change here\n", " y2 = [\n", " cHouse_write_execution_time,\n", " s3_write_execution_time,\n", " duckdb_write_execution_time,\n", " kdb_write_execution_time,\n", " ] # change here\n", " plt.bar(x - 0.2, y2, width)\n", " plt.bar(x + 0.2, y1, width)\n", " plt.xticks(\n", " x,\n", " [\n", " \"Click House\",\n", " \"S3 Parquet\",\n", " \"DuckDb\",\n", " \"Kdb+\",\n", " ],\n", " )\n", " plt.xlabel(\"Databases\")\n", " plt.ylabel(\"Seconds\")\n", " plt.legend([\"Write\", \"Read\"]) # ver\n", " plt.rcParams.update({\"font.size\": 8})\n", " plt.style.use(\"dark_background\")\n", " plt.show()\n", "\n", "\n", "plot(dark=True)" ] }, { "cell_type": "code", "execution_count": null, "id": "e58920d6-2a99-4ce4-9503-05873d61ffc3", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.11" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }