abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 17:33 | Nová verze

    Canonical vydal (email, blog, YouTube) Ubuntu 24.04 LTS Noble Numbat. Přehled novinek v poznámkách k vydání a také příspěvcích na blogu: novinky v desktopu a novinky v bezpečnosti. Vydány byly také oficiální deriváty Edubuntu, Kubuntu, Lubuntu, Ubuntu Budgie, Ubuntu Cinnamon, Ubuntu Kylin, Ubuntu MATE, Ubuntu Studio, Ubuntu Unity a Xubuntu. Jedná se o 10. LTS verzi.

    Ladislav Hagara | Komentářů: 3
    dnes 14:22 | Komunita

    Na YouTube je k dispozici videozáznam z včerejšího Czech Open Source Policy Forum 2024.

    Ladislav Hagara | Komentářů: 0
    dnes 13:22 | Nová verze

    Fossil (Wikipedie) byl vydán ve verzi 2.24. Jedná se o distribuovaný systém správy verzí propojený se správou chyb, wiki stránek a blogů s integrovaným webovým rozhraním. Vše běží z jednoho jediného spustitelného souboru a uloženo je v SQLite databázi.

    Ladislav Hagara | Komentářů: 0
    dnes 12:44 | Nová verze

    Byla vydána nová stabilní verze 6.7 webového prohlížeče Vivaldi (Wikipedie). Postavena je na Chromiu 124. Přehled novinek i s náhledy v příspěvku na blogu. Vypíchnout lze Spořič paměti (Memory Saver) automaticky hibernující karty, které nebyly nějakou dobu používány nebo vylepšené Odběry (Feed Reader).

    Ladislav Hagara | Komentářů: 0
    dnes 04:55 | Nová verze

    OpenJS Foundation, oficiální projekt konsorcia Linux Foundation, oznámila vydání verze 22 otevřeného multiplatformního prostředí pro vývoj a běh síťových aplikací napsaných v JavaScriptu Node.js (Wikipedie). V říjnu se verze 22 stane novou aktivní LTS verzí. Podpora je plánována do dubna 2027.

    Ladislav Hagara | Komentářů: 0
    dnes 04:22 | Nová verze

    Byla vydána verze 8.2 open source virtualizační platformy Proxmox VE (Proxmox Virtual Environment, Wikipedie) založené na Debianu. Přehled novinek v poznámkách k vydání a v informačním videu. Zdůrazněn je průvodce migrací hostů z VMware ESXi do Proxmoxu.

    Ladislav Hagara | Komentářů: 0
    dnes 04:11 | Nová verze

    R (Wikipedie), programovací jazyk a prostředí určené pro statistickou analýzu dat a jejich grafické zobrazení, bylo vydáno ve verzi 4.4.0. Její kódové jméno je Puppy Cup.

    Ladislav Hagara | Komentářů: 0
    včera 22:44 | IT novinky

    IBM kupuje společnost HashiCorp (Terraform, Packer, Vault, Boundary, Consul, Nomad, Waypoint, Vagrant, …) za 6,4 miliardy dolarů, tj. 35 dolarů za akcii.

    Ladislav Hagara | Komentářů: 12
    včera 15:55 | Nová verze

    Byl vydán TrueNAS SCALE 24.04 “Dragonfish”. Přehled novinek této open source storage platformy postavené na Debianu v poznámkách k vydání.

    Ladislav Hagara | Komentářů: 0
    včera 13:44 | IT novinky

    Oznámeny byly nové Raspberry Pi Compute Module 4S. Vedle původní 1 GB varianty jsou nově k dispozici také varianty s 2 GB, 4 GB a 8 GB paměti. Compute Modules 4S mají na rozdíl od Compute Module 4 tvar a velikost Compute Module 3+ a předchozích. Lze tak provést snadný upgrade.

    Ladislav Hagara | Komentářů: 0
    KDE Plasma 6
     (73%)
     (9%)
     (2%)
     (17%)
    Celkem 760 hlasů
     Komentářů: 4, poslední 6.4. 15:51
    Rozcestník

    Dotaz: "inner join" csv suborov v 2 adresaroch

    28.12.2015 15:04 Mike Stuffel
    "inner join" csv suborov v 2 adresaroch
    Přečteno: 632×

    Dobry den,

    uz dlhsie sa snazim efektivne vyriesit nasledujuci problem:

     

    Do 2 rozdielnych adresarov mi pribudaju CSV subory roznej velkosti ale rovnakeho formatu (su to key-value data). V tomto momente sa bavime asi o 30+ suboroch a celkovej velkosti cca 400GB. Je predpoklad ze objem dat bude do 1.5TB.

     

    Potreboval by som efektivne vyriesit "inner join" a vypisat len rovnake riadky zo suborov ulozenych v tychto 2 roznych adresaroch. Nieco ako:

    inner_join_csv_files /home/mike/data_A/*.csv /home/mike/data_B/*.csv > rovnake_riadky.csv

     

    Momentalne to riesim importom CSV suborov (obsahuju asi 5% duplicit) do 2 roznych tabuliek databazy Postgresql a naslednym SQL INNER JOIN prikazom (do 30 sekund mam vysledok). Toto uz nie je dostacujuce, pretoze import dalsieho CSV suboru trva aj viac ako 48 hodin koli pravidlam nad oboma tabulkami, ktore ignoruju duplicitne inserty (v databaze su len unikatne zaznamy aby sa pouzil index scan a nie sekvencny scan). Navyse cele to bezi len na obycajnom laptope :(.

     

    Hladam sposob akym by som mohol usetrit tych 48 hodin pri importe, som ochotny vo vysledku pripustit aj duplicity hlavne nech sa relevantne skrati doba. Je mi jedno aky nastroj alebo technologia sa na to pouzije hlavne nech to cele netrva 48 hodin :). Ak Vas napadne nejaky efektivny sposob ako vyriesit "inner join" CSV suborov v 2 adresaroch budem velmi vdacny.

    Odpovědi

    BigWrigley avatar 28.12.2015 15:48 BigWrigley | skóre: 33
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch

    Nad dvema soubory se da pouzit prikaz comm.

    Linux is like a wigwam - no windows, no gates and Apache inside.
    28.12.2015 15:58 NN
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Abych si to ujasnil. Mas dva adresare v kazdem ruzne velke csv soubory ktere obsahuji identicka data plus plevel a duplicity a ty chces ziskat cista data porovnanim obsahu. Je to tak? Shodna data jsou rozlozena ruznych v souborech nahodne, nebo se soubory podobaji(ie. je mozne porovnavat dvojici souboru nebo pouze cely balik)?
    28.12.2015 16:26 Mike Stuffel
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch

    Ano, mam dva adresare s CSV subormi. CSV maju rovnaku strukturu (key-value), ale roznu velkost a rozne nazvy. Chcem ziskat iba riadky, ktore sa nachadzaju v oboch adresaroch sucasne. Zhodne data su rozlozene v suboroch nahodne - teda sa musi porovnavat cely balik (oba adresare) sucasne.

     

    Teraz to robim importom do Postgresql a naslednym SQL INNER JOINom

    /home/mike/data_A/*.csv  ==> import do DB tabulka_A

    /home/mike/data_B/*.csv  ==> import do DB tabulka_B

     

    Import je strasne pomaly jeden CSV subor importujem aj 2 dni :(. Hladam teda efektivnejsie riesenie

    Josef Kufner avatar 28.12.2015 16:49 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Zkusil bych na dobu importu vypnout indexy. Nebo soubor importovat do nové tabulky bez indexů, a pak data opravit, udělat indexy a teprve potom dál zpracovávat.

    Základní myšlenka, data vložit do databáze a pak s tím pracovat, je dobrá, dělal bych to stejně.

    Existují ale i jiné databáze než SQL, a možná budou vhodnější pro tento objem dat. Co třeba Cassandra nebo něco podobného?
    Hello world ! Segmentation fault (core dumped)
    29.12.2015 12:50 Mike Stuffel
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Dakujem za tipy, este sa skusim pohrat so samotnym importom, povypinanim indexov, popripade pred importom rozdelit CSV-cka na mensie a tak importovat....

    z NoSQL databaz som skusal Mongo ale tam mi veslovene nesedel koncept map-reduce. S Cassandrou to vyzera onmnoho lepsie podporuje CQL co sa podoba na SQL.
    30.12.2015 10:01 Jindřich Makovička | skóre: 17
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Pokud jde o výkon, zkuste místo Cassandry ScyllaDB.
    30.12.2015 16:03 Mike Stuffel
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    dakujem za tip urcite sa pozriem aj na to
    28.12.2015 17:47 DIK
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Pokud umíš python tak se koukni na analytickou knihovnu panda , umí řešit joiny, duplicity, miss data, obecně se hodí práci s big data a je rychlá... DIK
    29.12.2015 13:13 Mike Stuffel
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch

    dakujem... toto bude asi presne to co som hladal ale budem sa musiet tomu este povenovat. s pytonom som zatial vobec nerobil, ale podla toho co som v rychlosti nasiel to vyzera celkom jednoducho... spravia sa 2 DataFramy a potom inner join medzi nimy.

    http://stackoverflow.com/questions/20906474/import-multiple-csv-files-into-pandas-and-concatenate-into-one-dataframe

    http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.join.html

    http://pandas.pydata.org/pandas-docs/stable/merging.html

    28.12.2015 17:58 Kit | skóre: 45 | Brno
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Na tohle používám key->value databáze, například DB4 nebo GDBM. Obsah prvního adresáře nasypu do databáze (jde to podstatně rychleji než u SQL databází) a obsah druhého pak řádek po řádku porovnám.
    Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
    29.12.2015 12:23 Mike Stuffel
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    presne s tymto pristupom som zacinal (Postgresql), no stal sa neefektivny v momente ked som potreboval takto porovnavat 60+GB CSV-ciek riadok po riadku s databazou. Teraz porovnavanie (inner join) nechavam databaze. Ma tu vyhodu ze vysledok mam do niekolkych sekund ale toto riesenie sa ukazuje tiez ako neefektivne pretoze import CSV suborov do databazy trva prilis dlho.

    29.12.2015 14:37 Kit | skóre: 45 | Brno
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    PostgreSQL nemá nic společného s DB4 ani GDBM. Proto jsem navrhl místo PostgreSQL jiné databáze.
    Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
    30.12.2015 15:56 Mike Stuffel
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Obsah prvního adresáře nasypu do databáze (jde to podstatně rychleji než u SQL databází) a obsah druhého pak řádek po řádku porovnám.
    PostgreSQL nemá nic společného s DB4 ani GDBM. Proto jsem navrhl místo PostgreSQL jiné databáze.

    Asi som spravne nepochopil. Nieco som som si precital o DB4. Je to cista key-value databaza.

     

    Ak ste to mysleli takto:

    /home/mike/data_A/*.csv ==> import do DB4 alebo GDBM

    /home/mike/data_B/*.csv ==> sekvencne citanie line-by-line + requesty na DB

     

    Toto riesenie sa ukazalo ako extremne pomale (mal som maly objem dat). pretoze sa musi robit sekvencne precitanie kazdeho riadku v CSV subore, nasledny request do DB a potom porovnanie ci je zhoda (inner join)

     

    Preto som sa rozhodol ze CSV naimportujem do Postgresql, ktory si to sam zaindexuje a urobi jednoduchym SELECTom vsetko za mna - vysledok mam takmer okamzite. No len tento import uz prestava vyhovovat :( pretoze trva aj viac ako 2 dni

    30.12.2015 16:01 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch

    No len tento import uz prestava vyhovovat :( pretoze trva aj viac ako 2 dni

    Opravdu se podívejte na to předělání importu (jak píšu níže), to je hlavní problém. Změna databáze je krok stranou a původní problém vlastně neřeší.
    -- OldFrog
    30.12.2015 16:18 Mike Stuffel
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch

    suhlasim.... na tom importe je nieco strasne zle.... uvazoval som ci sa da nejako zaobist bez databazy (aby som nemusel robit tak zdlhavy import) tj. nejako urobit "inner join" CSV suborov primo na filesysteme.

    Dokonca som chcel pouzit na tuto ulohu sphinxsearch alebo solr, tie si vedia velmi rychlo naindexovat txt subory (podporuju aj delty) a potom takmer okamzite vyhladavat, ale nedokazu urobit "inner join" 2 indexov :(

    30.12.2015 16:49 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Pokud to sphinxsearch/solr zaindexuje strukturovaně, pak to nebude rychlejší. A strukturovaně to potřebujete proto, abyste mohl udělat join. Jednodužšší postup než import do postgres databáze asi nenajdete.

    Csvkit sice umí sql dotazy přímo nad cvs, ale těžko to bude rychlejší, než postgres. Také si nejsem jist, zda umí join. Takže bych z rodiny csvkit nástrojů zkusil pouze csvsql - pokud je navržen s ohledem na velká data, může přinést zrychlení, protože možná vhodný postup importu řeší ve vlastní režii.

    Nejnadějnější bude otestovat pg_bulkload a pgloader. Tyto nástroje byly vytvořeny speciélně s ohledem na maximální rychlost. Osobně jsem neměl potřebu je zkoušet, vystačím s importem pomoc COPY. Každopádně, pokud importujete INSERTu, používáte nejpomalejší metodu a to i při vypnutých indexech a kontrolách.

    Na lehkou váhu bych nebral ani nastavení databáze (Postgres je ve výchozím stavu dost konzervativní) a vyzkoušel SSD disk (dramatické zrychlení IOPS).

    Pokud poskytnete vzorek dat, můžu to otestovat i já případně někdo jiný.
    -- OldFrog
    29.12.2015 13:11 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Zaměřil bych se na zrychlení toho importu, možná by to šlo zrychlit. Jak import probíhá?
    • singlerow INSERT
    • multirow INSERT
    • COPY
    Otestujte nástroje
    • csvkit
    • pg_bulkload
    • pgloader
    Podívejte se na další užitečná doporučení na How to speed up insertion performance in PostgreSQL - stackoverflow

    I když už jsme u toho, odkad pochází ty csv soubory a jak rychle vznikají?
    -- OldFrog
    30.12.2015 16:46 Mike Stuffel
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch

    import robim cez COPY

    copy tabulka_A(key,value) FROM '/home/mike/data_A/fileA.csv' DELIMITER ',' CSV

    copy tabulka_B(key,value) FROM '/home/mike/data_B/fileB.csv' DELIMITER ',' CSV

    Postgresql ma jednu neprijemnu vlastnost - COPY je jedna trasakcia: ak sa vyskytne duplicita vyhodi hlasku ERROR: duplicate key value violates unique constraint "key", a cely import zlyha. :(

    Preto som si napisal pravidlo, ktore ignoruje duplicitny insert do DB. Nieco na tento sposob http://dba.stackexchange.com/questions/30499/optimal-way-to-ignore-duplicate-inserts - a to moze byt kamen urazu.

    V podstate sa jedna o exporty z roznych transakcnych systemov, kde sa zaznamenavaju transakcne kroky (data_A) a "podozrive" transakcie (data_B). Tieto vystupy je nutne porovnavat, ked nastane zhoda nasledne manualne vyhodnotit.

    /home/mike/data_A/*.csv ==> prirastok je cca 8-10GB za tyzden

    /home/mike/data_B/*.csv ==> prirastok je cca 1GB za mesiac

    30.12.2015 17:04 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    A jsme myslím doma. Vypněte kontrolu na duplicitu a natáhněte to i s duplicitama. Podle popisu to vypadá, že ani duplicity kontrolovat nepotřebujete. Pokud ano, můžete duplicity zpracovat po importu až dodatečně - odmazat je, doplnit kontrolu a indexy. Pak teprve dělat dotaz.

    Jinak ohledně MERGE a UPSERT - MERGE není implmentovaný, UPSERT je v Postgres 9.5 (netestoval jsem).

    Velmi dobrý článek vysvětlující všechny problémy UPSERTu.

    Dejte vědět, zda se to zrychlilo.
    -- OldFrog
    30.12.2015 20:12 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Zkusil jsem si rychlost importu pro představu. Bez kontrol a indexů vložím milión záznamů za cca 19 sekund. S neunikátním indexem za cca 30sekund. Nastavení databáze je výchozí a s hodnotou shared_buffers = 128MB. Tyhle čísla by měly korespondovat s časem počtem a časem u vás. Korespondují?

    Vzorová data mají 312MB a milion řádek:
    $ wc -l file_A.csv
    1000000 file_A.csv
    
    $ ls -sh file_A.csv
    312M file_A.csv
    
    $ head -n3 file_A.csv
    2359;c2aa 4ebe 592c 2638 8c8f 5269 2e94 1381 59a9 cadc 2e84 b895 3295 7078 24a6 b512 df94 d803 e5d2 4c15 fc43 c818 49dd 86c5 1c60 90f9 f227 8738 5ef8 95ec e5f4 5288 106a 52b9 dc61 2a34 57a5 bd37 989d fd0e 078f 83b1 a157 b1b0 6399 8b9c a1af 21e3 fa39 7abd 8b9d 0615 bb5f 1afc f302 b0dc de59 18e9 a221 67f4 3a7e 6ea3 891a 619b;
    9765;8490 5573 28c2 e229 2519 b612 8745 fee1 e103 2476 3247 ad7d df5e 80ec f5f3 def8 fddc a313 50dd 7b6d 8949 25cd 5fed d7a8 177d b70d d6be 3aa7 8dc0 8df5 de28 34d3 bf03 6413 ca0d 2bb7 f397 a39a 7db0 72aa 7fad de31 4279 9a0b 93f1 4106 74c9 a3fa d1e9 afb7 dadb 0b61 bf0f c674 4c0e 1ecd c0c7 79c3 798d 471c dd5f 8125 dc52 7816;
    30671;75c5 f14d f72e 11c0 1833 8248 24b1 a939 38b2 d4d8 3e2e b129 22ad bc0d 2b41 b8da 61ea 18d2 dffb 32ad 83e0 118f 5c81 ae0f 8eb8 a495 a820 d30e 8fe1 a4f6 d234 6e36 a5f8 e17f aa2d 0953 fe34 bced c5bb 63b9 f460 41dc 59ef 8dd4 7043 9a32 54ca d20b 5393 bd72 0fb1 11dc 7980 4ebe eb73 6829 ecf2 b18e 8e52 a3b3 b43a 8ad0 111c b61c;
    
    Databáze
    CREATE DATABASE import
      ENCODING = 'UTF8'
      LC_COLLATE = 'cs_CZ.utf8'
      LC_CTYPE = 'cs_CZ.utf8';
    GRANT ALL ON DATABASE import TO postgres;
    GRANT ALL ON DATABASE import TO public;
    
    Tabulka:
    CREATE TABLE t1 (
      key integer,
      value text,
      extra text
    );
    
    Bez kontrol a bez indexu:
    $ psql -U postgres import -c "TRUNCATE t1;"
    TRUNCATE TABLE
    
    $ psql -U postgres import -c "DROP INDEX t1_key_idx;"
    ERROR:  index "t1_key_idx" does not exist
    
    $ time psql -U postgres -c "COPY t1(key,value,extra) FROM '/home/ondrej/Test/file_A.csv' DELIMITER ';' CSV;" import
    COPY 1000000
    
    real	0m19.562s
    user	0m0.003s
    sys	0m0.006s
    
    Bez kontrol s indexem:
    $ psql -U postgres import -c "TRUNCATE t1;"
    TRUNCATE TABLE
    
    $ psql -U postgres import -c "CREATE INDEX t1_key_idx ON t1 USING btree (key);"
    CREATE INDEX
    
    $ time psql -U postgres -c "COPY t1(key,value,extra) FROM '/home/ondrej/Test/file_A.csv' DELIMITER ';' CSV;" import
    COPY 1000000
    
    real	0m29.042s
    user	0m0.002s
    sys	0m0.004s
    
    Přelití jedinečných záznamů do jiné tabulky:
    $ time psql -U postgres import -c "CREATE TABLE t2 AS SELECT DISTINCT ON(key) * FROM t1;"
    SELECT 32768
    
    real	0m15.888s
    user	0m0.001s
    sys	0m0.008s
    
    Doplnění jedinečného indexu (t2 neobsahuje duplicity, t1 ano):
    $ psql -U postgres import -c "CREATE UNIQUE INDEX t2_key_idx ON t2 USING btree (key);"
    CREATE INDEX
    
    $ psql -U postgres import -c "DROP INDEX t1_key_idx; CREATE UNIQUE INDEX t1_key_idx ON t1 USING btree (key);"
    ERROR:  could not create unique index "t1_key_idx"
    DETAIL:  Key (key)=(12063) is duplicated.
    
    Počty řádků v tabulce:
    $ psql -U postgres import -c "SELECT count(*) FROM t1;"
      count  
    ---------
     1000000
    (1 řádka)
    
    $ psql -U postgres import -c "SELECT count(*) FROM t2;"
     count 
    -------
     32768
    (1 řádka)
    
    Verze databáze:
    $ psql -U postgres import -c "SELECT version();"
                                                       version                                                   
    -------------------------------------------------------------------------------------------------------------
     PostgreSQL 9.4.5 on x86_64-redhat-linux-gnu, compiled by gcc (GCC) 5.1.1 20150618 (Red Hat 5.1.1-4), 64-bit
    (1 řádka)
    
    A s Potgres 9.5.rc1 a UPSERT:
    $ psql -U postgres -h localhost -p 5434 import -c "TRUNCATE TABLE t2;"
    TRUNCATE TABLE
    
    $ psql -U postgres -h localhost -p 5434 import -c "DROP INDEX IF EXISTS t2_key_idx;"
    DROP INDEX
    
    $ psql -U postgres -h localhost -p 5434 import -c "CREATE UNIQUE INDEX t2_key_idx ON t2 USING btree (key);"
    CREATE INDEX
    
    $ time psql -U postgres -h localhost -p 5434 import -c "INSERT INTO t2 SELECT * FROM t1 ON CONFLICT (key) DO NOTHING;"
    INSERT 0 32768
    
    real	0m6.932s
    user	0m0.005s
    sys	0m0.006s
    
    $ psql -U postgres -h localhost -p 5434 import -c "SELECT version();"
                                                      version                                                  
    -----------------------------------------------------------------------------------------------------------
     PostgreSQL 9.5rc1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-55), 64-bit
    (1 řádka)
    
    -- OldFrog
    30.12.2015 23:28 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Ještě jsem to zkusil pomocí pg_bulkload a pgloader. Ostatní parametry jsou stejné, Postgres je 9.5.rc1.

    Pomocí pg_bulkload:
    $ time pg_bulkload -h localhost -p 5434 -U postgres -d import file_A.ctl
    NOTICE: BULK LOAD START
    NOTICE: BULK LOAD END
    	0 Rows skipped.
    	1000000 Rows successfully loaded.
    	0 Rows not loaded due to parse errors.
    	0 Rows not loaded due to duplicate errors.
    	0 Rows replaced with new rows.
    
    real	0m10.887s
    user	0m0.002s
    sys	0m0.004s
    
    A pomocí pgloader:
    $ pgloader --type csv --field key --field value --field extra --with "drop indexes" --with "disable triggers" --with "fields terminated by ';'" file_A.csv postgres://postgres:***@localhost:5434/import?tablename=file_A
    2015-12-30T22:56:31.075000+01:00 LOG Main logs in '/tmp/pgloader/pgloader.log'
    2015-12-30T22:56:31.079000+01:00 LOG Data errors in '/tmp/pgloader/'
           table name       read   imported     errors      total time       read      write
    -----------------  ---------  ---------  ---------  --------------  ---------  ---------
                fetch          0          0          0          0.011s                     
    -----------------  ---------  ---------  ---------  --------------  ---------  ---------
               file_a    1000000    1000000          0         47.886s    47.148s   18.913s
    -----------------  ---------  ---------  ---------  --------------  ---------  ---------
    Total import time    1000000    1000000          0         48.109s    47.148s   18.913s
    
    -- OldFrog
    Aleš Janda avatar 29.12.2015 13:17 Aleš Janda | skóre: 23 | blog: kýblův blog | Praha
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Pokud mají být ty řádky opravdu stejné (ve všech sloupcích; pak je otázka, k čemu to je), stačilo by

    cat /home/mike/data_A/*.csv /home/mike/data_B/*.csv | LANG=C sort | uniq -d

    (vezmeš všechno, seřadíš, vypíšeš jen duplicitní)

    Pokud by se to mělo dělat opakovaně nad stejnýma souborama, pak se vyplatí je seřadit předem (někam vedle) a potom pomocí

    LANG=C sort -m soubor /home/mike/data_A/*.serazeno.csv /home/mike/data_B/*.serazeno.csv | uniq -d

    už seřazené soubory zmergoat a zase vypsat duplicity.

    Pokud bys nechtěl vyloženě duplicitní řádky, ale duplicitní jen některé klíče, tak bych ty klíče dal jako první sloupec, seřadil, zmergoval a nějakým vlastním skriptem rozhodl, jestli ty řádky teda duplicitní jsou nebo ne a podle toho vypsal :-) Nicméně to už je trivialita, to hlavní (seřazení) už budeš mít hotové.

    To LANG=C je dobré uvádět, pokud nechceš vyloženě třídit podle nějakých lokálních specifikací, je to pak rychlejší.

    Všechno toto všechno bude trvat řádově méně než 48 hodin :-)
    29.12.2015 14:41 dustin | skóre: 63 | blog: dustin
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Nevím, jak jsou uniq a sort napsané, snad jim bude stačit paměť...
    29.12.2015 14:53 Jooky (inactive) | skóre: 39 | blog: Jooky | Bratislava
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    urcite nebude :) ... tu sa nebavime o par MB suboroch, ale cca 400GB. V tom pripade nie je ina moznost ako pouzit databazu. Ked je problem take mnozstvo dat dostat do databazy v rozumnom case, tak je nejaky problem so samontym importom a to treba poriesit. Ako uz bolo spomenute. Vypnut indexy, natlacit data do databazy. Zapnut indexy a potom sa moze robit akykolvek select nad datami. Dalsie pridavanie je uz lepsie riesit "prihadzovanim" novych suborov, nie znova celym importom. Ak to nepojde idealne, tak treba osetrit aj tento inkrementalny import (vypinanim klucov, spravit to ako jednu transakciu, etc.).
    Aleš Janda avatar 29.12.2015 18:30 Aleš Janda | skóre: 23 | blog: kýblův blog | Praha
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Paměť stačit bude, neboj :-)

    uniq nepotřebuje paměť žádnou (porovnává max. dva řádky za sebou), sort si pak setříděné mezivýsledky, které se mu nevejdou do paměti, ukládá do tempu. Tj. v tempu musí být ideálně tolik místa, jak je velký zdrojový soubor.

    Sesortit 400 GB tedy není problém, pokud je dost místa na disku. Na disku je zřejmě místa dost, když teď těch 400 GB cpe do databáze, kde jsou i indexy, režie apod.

    Pro jednorázové použití by měl být sort + uniq o dost efektivnější než databáze. Jednak kvůli absenci dodatečné režie (parsování dotazu apod.), jednak proto, že databáze obecně nejsou moc optimalizovány pro import a dá se s tím dělat jen hodně málo (před časem jsem řešil zrovna pro PostgreSQL).

    Řešení sort + uniq (v trochu jiném podání, volám to opakovaně) mám použito na jednom webu, kde se to sortí denně, cca 100 GB dat.
    29.12.2015 19:54 Jooky (inactive) | skóre: 39 | blog: Jooky | Bratislava
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    o tom, ze si sort uklada medzivysledky do tempu som nevedel, no stale to neriesi problem :) ... SQL INNER JOIN sa cez sort spravit neda.
    30.12.2015 17:20 Mike Stuffel
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch

    takto to funguje teraz. Dostanem novy CSV subor a ten naimportujem do databazy.

    CREATE TABLE tabulka_A ( key varchar(16) PRIMARY KEY, value varchar(128) );

    vypinanie/zapinanie primarneho kluca je vhodne, kym mam zarucene ze v CSV suboroch nebudu duplicity (teraz je ich cca 5%) - v databaze by som ich nechcel mat. Pri importe chcem mat zapnuty primarny key koli duplicitam.

    ak by som pred importom vypol primarny kluc riskoval by som ze v databaze by boli duplicity a nesiel by potom zapnut. Musel by som vsetky duplicity mazat rucne a az tak ho zapnut (pain in ass).

    30.12.2015 18:29 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Ty duplicity si můžete zpracovat i dodatečně. Postgres 9.5 umí výše zmiňovaný UPSERT, takže to nalejte třeba do jedné tabulky bez kontroly duplicity a pak přelejte do cílové tabulky s ON CONFLICT DO NOTHING:
    CREATE TABLE t2 ...;
    INSERT INTO t2 AS SELECT * FROM t1 ON CONFLICT (...) DO NOTHING;
    
    Implementace v databázi bude rychlejší než vaše funkce (kdoví jestli je správně implementovaná). Anebo:
    CREATE TABLE t2 AS SELECT DISTINCT ON(...) FROM t1;
    
    Chce si to s tím trochu pohrát. Kolik řádků má vlastně těch zmiňovaných 400GB?
    -- OldFrog
    31.12.2015 09:08 Mike Stuffel
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Chce si to s tím trochu pohrát. Kolik řádků má vlastně těch zmiňovaných 400GB?
    jj budem sa tomu musiet povenovat a tiez potunit konfigurak - mam teraz defaultny. Momentalne je tam 4184023358 riadkov. Ak sa objem bude blizit ku 1.5TB budem sa musiet zamysliet ako pokracovat dalej. Myslite ze Postgresql je vhodny na spracovanie aj takto velkych (key-value) dat? Na SQL databazach sa mi paci, ze behom kratkej chvile a velmi jednoduchym sposobom dokazem dostat pozadovane data.
    31.12.2015 09:57 NN
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Uvazoval bych o tom, zda zminovane transakcni systemy, nemuzou ukladat do databaze 'inline' bez tohoto manualniho mezikroku.
    Josef Kufner avatar 31.12.2015 14:08 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Uvažoval jsi o způsobu, jak se řádků zbavit? Spočítat si nějaký mezivýsledek a o pár řádů zmenšit množství dat pro další zpracování.
    Hello world ! Segmentation fault (core dumped)
    31.12.2015 14:11 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Hmm, 4184023358 řádků je dost. Pokud bych aproximoval svoje testy, tak by se tento počet řádků importoval 10 (pg_bulkload) až 24 (COPY) hodin. Pokud by byly databáze i zdrojová data v ramdisku, bylo by to asi polovic (tuto variantu jsem ale v testech výše neuváděl).

    Doporučil bych se zamyslet, zda by bylo možné provádět importy průběžně. Pokud Vám přibude 10GB týdně, tak těchto 10GB budete importovat asi půl hodiny, což už je v pohodě.

    Jinými slovy - upravte postup zpracování tak, aby se nemuselo pracovat s takovým objemem naráz. To znamená zpracovávat csv soubory častěji (jednoduše nasadit logrotate?) anebo logovat do databáze rovnou (asi větší zásah postupu). To jsou systémová řešení. Postgres má limit 32TB na tabulku, limit na velikost databáze ani počet řádků v tabulce není řádný. Pokud přikoupíte RAM a SSD disk, vystačíte s tím hodně dlouho.

    Uvědomte si, že alternativní databázové systémy nejsou zázračně rychlejší, jsou pouze lépe škálovatelné (pro více procesorů, více počítačů, s paralelizací a podporou pro dotazy nad několikařádově větším objemem dat). Vy máte jen jeden počítač a objem dat, který by pro relační databázi neměl být zas takový problém.

    Ohledně použití csv jako storage pro databázi - možná to jde, ale dotazy nad těmi daty budou asi dost pomalé, takže ve výsledku to může ještě pomalejší.
    -- OldFrog
    20.1.2016 15:06 Mike Stuffel
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Rad by som sa podakoval vsetkym ktori prispeli radou, najma p. OldFrog {Ondra Nemecek}. Po testoch navrhovanych rieseni sa ukazalo, ze uzkym hrdlom je hardware. Po prechode na SSD + dokupenie RAM + migracia a tuning Postgresql 9.5 sa doba importu vyznamne znizila na cca 6-8 hodin.
    20.1.2016 18:25 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
    Rozbalit Rozbalit vše Re: "inner join" csv suborov v 2 adresaroch
    Tak to jsem rád, že to šlape :-)
    -- OldFrog

    Založit nové vláknoNahoru

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.