abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
eParkomat, startup z ČR, postoupil mezi finalisty evropského akcelerátoru ChallengeUp!
Robot na pivo mu otevřel dveře k opravdovému byznysu
Internet věcí: Propojený svět? Už se to blíží...
včera 22:44 | Komunita

Joinup informuje, že Mnichov používá open source groupware Kolab. V srpnu byl dokončen dvouletý přechod na toto řešení. V provozu je asi 60 000 poštovních schránek. Nejenom Kolabu se věnoval Georg Greve ve své přednášce Open Source: the future for the European institutions (SlideShare) na konferenci DIGITEC 2016, jež proběhla v úterý 29. listopadu v Bruselu. Videozáznam přednášek z hlavního sálu je ke zhlédnutí na Livestreamu.

Ladislav Hagara | Komentářů: 1
včera 15:30 | Zajímavý projekt

Společnost Jolla oznámila v příspěvku Case study: Sailfish Watch na svém blogu, že naportovala Sailfish OS na chytré hodinky. Využila a inspirovala se otevřeným operačním systémem pro chytré hodinky AsteroidOS. Použita je knihovna libhybris. Ukázka ovládání hodinek na YouTube.

Ladislav Hagara | Komentářů: 5
včera 14:15 | Nová verze

Byla vydána verze 7.1.0 skriptovacího jazyka PHP používaného zejména k vývoji dynamických webových stránek. Jedná se o první stabilní verzi nejnovější větvě 7.1. Přehled novinek v dokumentaci. Podrobnosti v ChangeLogu. K dispozici je také příručka pro přechod z PHP 7.0.x na PHP 7.1.x.

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

Google Chrome 55 byl prohlášen za stabilní. Nejnovější stabilní verze 55.0.2883.75 tohoto webového prohlížeče přináší řadu oprav a vylepšení (YouTube). Opraveno bylo také 36 bezpečnostních chyb. Mariusz Mlynski si například vydělal 22 500 dolarů za 3 nahlášené chyby (Universal XSS in Blink).

Ladislav Hagara | Komentářů: 4
včera 11:55 | Pozvánky

Máte rádi svobodný software a hardware nebo se o nich chcete něco dozvědět? Přijďte na 135. sraz spolku OpenAlt, který se bude konat ve čtvrtek 8. prosince od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Sraz bude tentokrát tématický. Bude retro! K vidění budou přístroje jako Psion 5mx nebo Palm Z22. Ze svobodného hardwaru pak Openmoko nebo čtečka WikiReader. Přijďte se i vy pochlubit svými legendami, nebo alespoň na pivo. Moderní hardware má vstup samozřejmě také povolen.

xkucf03 | Komentářů: 0
včera 00:10 | Nová verze

Byla vydána verze 3.2 svobodného systému pro detekci a prevenci průniků a monitorování bezpečnosti počítačových sítí Suricata. Z novinek lze zmínit například podporu protokolů DNP3 a CIP/ENIP, vylepšenou podporu TLS a samozřejmě také aktualizovanou dokumentaci.

Ladislav Hagara | Komentářů: 0
1.12. 21:00 | Nová verze

Byla vydána beta verze Linux Mintu 18.1 s kódovým jménem Serena. Na blogu Linux Mintu jsou hned dvě oznámení. První o vydání Linux Mintu s prostředím MATE a druhé o vydání Linux Mintu s prostředím Cinnamon. Stejným způsobem jsou rozděleny také poznámky k vydání (MATE, Cinnamon) a přehled novinek s náhledy (MATE, Cinnamon). Linux Mint 18.1 bude podporován až do roku 2021.

Ladislav Hagara | Komentářů: 0
1.12. 16:42 | Nová verze

Byl vydán Devuan Jessie 1.0 Beta 2. Jedná se o druhou beta verzi forku Debianu bez systemd představeného v listopadu 2014 (zprávička). První beta verze byla vydána v dubnu letošního roku (zprávička). Jedna z posledních přednášek věnovaných Devuanu proběhla v listopadu na konferenci FSCONS 2016 (YouTube, pdf).

Ladislav Hagara | Komentářů: 0
1.12. 15:16 | Komunita

Na GOG.com začal zimní výprodej. Řada zlevněných her běží oficiálně také na Linuxu. Hru Neverwinter Nights Diamond lze dva dny získat zdarma. Hra dle stránek GOG.com na Linuxu neběží. Pomocí návodu ji lze ale rozběhnout také na Linuxu [Gaming On Linux].

Ladislav Hagara | Komentářů: 1
1.12. 13:14 | Bezpečnostní upozornění

Byla vydána verze 2.7.1 živé linuxové distribuce Tails (The Amnesic Incognito Live System), jež klade důraz na ochranu soukromí uživatelů a anonymitu. Řešeno je několik bezpečnostních problémů. Aktualizován byl především Tor Browser na verzi 6.0.7. Tor Browser je postaven na Firefoxu ESR (Extended Support Release) a právě ve Firefoxu byla nalezena a opravena vážná bezpečnostní chyba MFSA 2016-92 (CVE-2016-9079, Firefox SVG Animation

… více »
Ladislav Hagara | Komentářů: 0
Kolik máte dat ve svém domovském adresáři na svém primárním osobním počítači?
 (32%)
 (24%)
 (29%)
 (7%)
 (5%)
 (3%)
Celkem 759 hlasů
 Komentářů: 50, poslední 29.11. 15:50
Rozcestník
Reklama

Dotaz: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie

17.5.2012 12:08 adrinko | skóre: 22
MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Přečteno: 979×
ahojte, mam takyto dotaz. V tabulke si pre kazdeho usera ukladam zaznamy, t.j. tabulka tbl ma stlpce id(auto_increment), user_id, dni. Ked si user edituje dni, potreboval by som zmazat dni a vsetky dni po kliknuti na tlacidlo odoslat opatovne ulozit do db. Nemam problem prikazom zmazat vsetky userove riadky a nasledne vlozit vsetky aktualne riadky, avsak obavam sa, ci to moc nezatazi databazovy server... pocitam s tym, ze kazdy user bude mat stovky zaznamov a spolu budu mozno tisicky userov. Preto by ma zaujimalo, ci toto nebude robit problem serveru z hladiska vykonu. Diky moc za pomoc :)

P.S. mohol by niekto namietat, preco tie userove zaznamy jednoducho neupdatujem, ale bolo by to podla mna narocnejsie kazdy jeden zaznam skontrolovat a nasledne updatovat alebo neupdatovat, ako ich jednoducho vsetky naraz zmazat a nasledne znovu insertnut.

Řešení dotazu:


Odpovědi

17.5.2012 12:32 Kit
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Ještě je možná třetí cesta: Sdělit databázi, aby si ty záznamy jediným dotazem před updatem zkontrolovala sama. Číst, modifikovat, mazat a vkládat - to jsou 4 zbytečné operace, které se dají vložit do jednoho atomického dotazu.
18.5.2012 14:29 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Jedním dotazem to neuděláš. V mysql uděláš insert on duplicate row update, ale smazání uděláš zvlášť.

Pokud má jít o výkon, tak bych udělal temporary table, vložil do ní data pro změnu a pak udělal dotazy:

DELETE FROM tabulka WHERE (user_id, den) NOT IN (SELECT user_id, den FROM docasna) 
INSERT INTO tabulka (...) SELECT (...) FROM DOCASNA ON DUPLICATE ROW UPDATE tabulka.dalsidata = VALUES(Dalsidata)
27.5.2012 14:19 Kit
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Je v tom sice několik drobných chyb, ale principiálně mi to připadá jako dobré řešení.
Tarmaq avatar 17.5.2012 17:18 Tarmaq | skóre: 39
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
ten umelohmotny sloupec id je tam dobry k cemu? Ja bych tam nechal jen user_id a datum a nad tim vytvoril slozeny primarni klic..

potom bych tedy tedy klasicky udelal
DELETE FROM tbl WHERE user_id = 1234;

INSERT INTO tbl (user_id, datum)
SELECT 1234, '2012-04-04' UNION
SELECT 1234, '2012-04-05' UNION
SELECT 1234, '2012-04-09'
samozrejme se pocita s tim, ze nebudes poustet N insertu z phpka, ale ze si slozis ten select uz na strane php
Don't panic!
18.5.2012 14:17 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Umělý primární klíč je dobrá věc. Co když např. při evoluci aplikace bude uživatel moci přidávat více záznamů s jedním dnem (rozlišené něčím dalším)? Další věc je, že některé nástroje na existenci jednoduchého PK spoléhají, popř. při jeho existenci jsou věci jednodušší.

To, co píšeš, naprosto nesouvisí s tím, zdali je nad daty primární klíč nebo ne - max by mělo smysl ho udělat clustered.

Tarmaq avatar 18.5.2012 15:52 Tarmaq | skóre: 39
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Nevim ja moc tech vyhod teda nevidim. Pokud bych tam chtel casem mit vice zaznamu ke stejnemu dni, tak bych prece vytvoril dalsi tabulku abych nemel denormalizovanou databazi, nebo proste staci ten umelej klic vytvorit pak ne? Naopak vidim spis nevyhody. Clovek musi vic joinovat misto toho aby pouzil hodnotu kterou uz ma v ruce. Data ztraceji na prehlednosti.
Don't panic!
18.5.2012 16:51 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Další tabulku? Odkazující se na tudle tabulku předpokládám pomocí primárního klíče? Hmmmm. takže podle Tebe budeš mít jednu tabulku [uživatel, den] a druhou [uživatel, den, data]. Tomu říkám vyloženě užitečná struktura.

Jinak co myslíš tou denormalizovanou databází nechápu, protože přidání umělého klíče nikterak neporušuje normalitu databáze, žádná z pravidel normality nic neříká o tom, že tabulka nemůže mít klíče dva. Stejnětak normální formu neporuší přidání dalšího neklíčového atributu k tabulce s umělým PK (k tabulce bez něj ale ano - a proto je struktura s umělým PK pružnější).

Vytvořit si umělej klíč dodatečně můžeš, ale musíš upravit všechna místa v kódu, kde se na tu tabulku odkazuješ, protože vždy musíš rozlišit, zda chceš pracovat se všemi záznamy daného dne, nebo jen s jedním. Zatímco pokud máš od začátku umělej primární klíč, tak od začátku můžeš odlišovat sémantiku: klíč uživatel,den = všechny záznamy, id = jeden záznam, i když to v této chvíli znamená totéž. - Jinými slovy: jakmile v některé z DB tabulek uděláš z klíčového atributu neklíčový, koleduješ si o průšvih; proto se používají umělé klíče, protože u nich je tato možnost zpravidla vyloučena (i když zvěrstva se najdou vždy).

Víc joinovat? Proč? Co Ti brání všude v případě potřeby použít původní klíč, copak je v db zákaz používat odkazy na cokoli mimo PK? Od čeho jsou sekundární indexy? Jedině snad to, že vícehodnotové FK jsou ošklivé a znepřehledňují databázi (a z výše popsaných důvodů jsou i špatně rozšiřitelné) a proto se moc nepoužívají. Ale to jen ukazuje na to, že umělý jednohodnotový PK má své opodstatnění.

19.5.2012 11:25 kuka
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Synteticky PK ma smysl tam, kde na nej odkazuji cizi klice z jinych tabulek. Pokud tomu tak neni, stejne se nikdy nepouzije - volajici se totiz nijak nedozvi, ktera hodnota tohoto klice ho zajima. Pro docasne zapamatovani radku napr. pro pozdejsi update ma vetsina databazi jine prostredky (napr Oracle rowid), ktere jsou vykonove lepsi. U malych tabulek to muze byt celkem jedno, ale uz jsem videl umely PK "pro jistotu" u tabulek se stamiliony radku a to uz je peknych par desitek GB vzduchu, ktery se musi zalohovat atd. Pro takovy zbytecny PK musi totiz existovat index, ktery muze byt klidne vetsi nez cela tabulka a musi se pri vsech operacich udrzovat, coz pochopitelne zpomaluje.

Takze kdyz to shrnu - umely PK neni sam o sobe ani dobra ani spatna vec, jsou jen jeho dobra a spatna pouziti. Vzdy zalezi na konkretnim datovem modelu a scenarich pouziti. Zde nemame dostatek informaci, takze rozhodovani o tom, zda tam tazatel ma nebo nema takovy klic mit, je bezpredmetne.
rADOn avatar 18.5.2012 18:13 rADOn | skóre: 44 | blog: bloK | Praha
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
P.S. mohol by niekto namietat, preco tie userove zaznamy jednoducho neupdatujem, ale bolo by to podla mna narocnejsie kazdy jeden zaznam skontrolovat a nasledne updatovat alebo neupdatovat, ako ich jednoducho vsetky naraz zmazat a nasledne znovu insertnut.
Dám ti dobrou radu jak postupovat při databázových optimalizacích a vyždímat maximální výkon. Připraven? "Neser se do věcí kterým nerozumíš." :-) Neber to prosím zle, ale tvoje dobře míněná snaha má přesně opačný účinek. Takovým neustálým přerovnáváním řádků dosáhneš po čase obrovské a úplně zbytečné fragmentace. Pokud má ta tabule nějakou decentní velikost, skočíš tak že víc času strávíš zbytečným iowaitem až se natáhne jeden blok z opačného konce disku než samotným updatováním. Navíc UPDATE spojený se SELECTem má databáze šanci nějak vyoptimalizovat (MySQL má dokonce speciální syntaxi na tohle) zatímco když jí to rozdrobíš, nevymyslí nic ani ten nejvydumanější query optimizer. Může s tím být spojené i další penále kvůli přepočítávaní indexů, vytlačování horkých řádek z keší etc…

Hledáš tohle tohle nebo tohle. (to už je poněkolikáté, asi si to nechám vytisknout na tričko :-))

Pokud nepřidáváš nové řádky, může být nejlepší taktika updatnout prostě všechno, padni komu padni. Většina databází je dost chytrá a řádky které se nemění prostě ignoruje.
"2^24 comments ought to be enough for anyone" -- CmdrTaco
18.5.2012 21:43 podlesh
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
+1

Ještě bych přidal - konkrétně v DB2 je delete+insert vůbec to nejhorší co se může udělat (existuje tedy možnost označit tabulku speciálním příznakem aby s tím počítala, ale i tak to není žádný zázrak).
18.5.2012 23:26 adrinko | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
okej, rád si nechám poradiť, veď každý raz nerozumel niečomu, aby až potom mohol tomu porozumieť. čo ale v prípade, že do databázy dám takéto stĺpce: user, group, datetime_from, datetime_to? ide mi o to, aby čo najefektívnejšie boli uložené dáta do db. Zoberme príklad - nejaké dáta už má niektorý user uložené v db (jeden user viac záznamov, zhoduje sa stĺpec user a group, ale nie datetime_from, datetime_to - môže byť teda x riadkov pre takéhoto usera s rôznymi dátumami). Teraz tá horšia časť - pri opätovnom refreshy php skriptu sa pre daného usera vygenerujú nové dáta (s viacerými novými časmi) - a práve tieto najaktuálnejšie potrebujem uložiť do db a tých pôvodných sa zbaviť (tie ma už nezaujímajú). Potrebujem teda určite replace alebo insert on duplicate alebo nejakú inú funkciu?
19.5.2012 02:04 DK
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
pokud to spravne chapu, staci jednoduche replace / update
pripadne pokud jeste nekontrolujes, zda tam uzivatel ma zaznam, tak insert on duplicate

ale spis napis, co presne resis, pak ti tu dokazeme poradit nejlepe (ono se treba zjisti, ze to, co delas je naprosto zbytecne a jde to resit uplne jinak - treba docasne veci flaknout do sessions)
19.5.2012 02:40 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
- Děláš machra, ale např. v MVCC architekturách databází je každej update v podstatě úplně totéž co delete a insert (tzn. postgresql, oracle, firebird).

- U neMVCC databází jsou většinou data uložená clustrovaná dle primárního klíče (či jiného daného indexu). V tu chvíli záznamy prostě nebudou fragmentovány. Pokud by už k fragmentaci došlo, tak nikoli na provni záznamů, ale stránek: tady je pak naopak větší šance, že při DELETE a následném INSERTU budou stránky, ve kterých leží vkládaná data u sebe. Naopak pokud půlku záznamů oupdatujeme a druhou vložíme nově, tak se riskuje fragmentace více.

- UPDATE spojený se SELECTEM query optimizer vyoptimalizuje úplně stejně, jako DELETE a INSERT. To, o co jde je počet diskových operací a každá databáze si po DELETE natáhne patřičnou stránky do paměti, takže následnej insert je v podstatě zadarmo. Výhoda UPDATE oproti INSERT/DELETE je v tom, že se nemusí dvakrát zbytečně upravovat indexy.

- REPLACE je defakto cukr pro DELETE a INSERT. To ušetří v podstatě jen čas na kompilaci dotazu.

- Vyhledávání po jednom při hodně záznamech opravdu blbé je: nikoli kvůli scrollování (to se musí u mazání dělat taky), ale pokud je těch záznamů více, tak kvůli komunikaci s DB a kompilaci mnoha dotazů a komunikaci s db. Řešení s INSERT ON DUPLICATE ROW UPDATE sice vhodné je, ale jen pro malý počet řádků. Pro větší počet řádků se může chovat hůře, než jeden příkaz INSERT a jeden DELETE: ty bude levně chroustat nad pár datovými stránkami. Pokud se takovéto řešení použije, tak je třeba nejprve nové dát do dočasné tabulky a pak tabulku opravit jedním DELETEM a jedním INSERT ON DUPLICATE ROW UPDATE.

- Poslední Tvé tvrzení IMHO není pravda (už proto, že na těch tabulkách mohou být pověšené triggery, on update current timestamp a podobná zvířátka)

- Když to tak po sobě čtu, Tak bych měl i pro Tebe jednu radu. Připraven? Tvoje rada tazateli platí i Tobě. :-)
19.5.2012 02:42 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
(pozn. v Mysql je MVCC engine např. Falcon)
19.5.2012 12:07 kuka
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Tak konkretne pro Oracle to takto jednoduse nefunguje. Delete a nasledujici insert rozhodne nejsou totez jako update, alespon v naproste vetsine pripadu, a to nejen semanticky, ale i z hlediska vykonu. Ciste na urovni tabulky se insert typicky neprovede do stejneho bloku jako delete, napr. s ohledem na pctused to ani nemusi jit, i kdyby se to databaze snazila delat (AFAIK se o to vubec nesnazi), zatimco update pochopitelne ano. Oba (pripadne vice pokud radek preteka} zasazene bloky se pak musi projevit v logu, coz predstavuje zbytecny zapis na disk a to je nejdrazsi operace. Samostatnou kapitolou je udrzba indexu a kontrola cizich klicu, coz mimo jine muze zpusobit i faktickou nemoznost nahrazeni updatu deletem a insertem kvuli constraintum. Ze se vyvolaji uplne jine triggery je pak uz jen takova tresnicka na dortu.
okbob avatar 19.5.2012 19:22 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Minimálně v PostgreSQL je rozdíl jestli uděláte DELETE, INSERT nebo UPDATE. A to neberu v potaz indexy. V případě databází, které navíc používají klastrovaný index a navíc budou používat MVCC, tak DELETE/INSERT může být o dost horší. S většinou co je výše uvedené souhlasím, jen bych rozporoval fakt, že v MVCC je DELETE/INSERT téměř stejný co UPDATE - není, bude to o něco málo náročnější (on totiž DELETE je skoro jako UPDATE) a pak DELETE/INSERT ~ UPDATE/INSERT a to je > pouhý UPDATE.

offtopic: Falcon je mrtvý projekt :( - vypadalo to nadějně, ale nedokázali to dotáhnout do konce. Místo toho se v Oracle soustředili na integraci novějších verzí InnoDB (což je živý MVCC engine pro MySQL) a u MariaDB připravují Maria engine - což by měl být bezpečný netransakční nástupce MyISAM.

Jinak fakt je ten, že tazatelem zmiňovaná optimalizace nemá smysl - ale když se zeptal, tak není úplně ztracenej :) - Když si vzpomenu, co my jsme dělali z MSSQL a neměli jsme tušení jak to funguje :(. Chce se to pořád učit - přečíst si něco i interních mechanismech té či oné db, a nebát se si vyzkoušet chování na prototypu u sebe.

Pokud je mi známo alespoň pro PostgreSQL, tak z pohledu optimalizace je INSERT, UPDATE, DELETE více-méně SELECT. Jen se to liší v té poslední fázi.
rADOn avatar 21.5.2012 13:28 rADOn | skóre: 44 | blog: bloK | Praha
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Když to tak po sobě čtu, Tak bych měl i pro Tebe jednu radu. Připraven? Tvoje rada tazateli platí i Tobě.
Touché… Ale já se tím řídím :-) Doby kdy jsem ztrácel čas zkoumáním intimních detailů fungování databází už je dávno pryč. Časem jsem dospěl k tomu že 1) Databáze nepíší blbci. Dokonce ani MySQL ne :-) 2) Většinu věcí umí DB zoptimalizovat lépe než já. Nejlepší co můžu udělat je neplést se do cesty, maximálně občas trochu napovědět. 3) Když už výjimečně udělám nějakou rádobyvyfikundovanou optimalizaci tak o pár verzí DB dál může mít nulový nebo právě opačný efekt.

Nad velkými daty to samozřejmě tak jednoduché není, ale pro mrzácké tisíce uživatelů a stovky tisíc řádků o kterých mluvil Adrinko to IMO platí.
U neMVCC databází jsou většinou data uložená clustrovaná dle primárního klíče (či jiného daného indexu). V tu chvíli záznamy prostě nebudou fragmentovány…
V MySQL/InnoDB se clusteruje pouze obsah primárního klíče… zbytek řádky == seek. Sklepávání řádek do stejného bloku jak píšeš může hodně pomoci, o tom žádná. Ale třeba v MySQL to vede AFAIK k zamykání celých bloků i bloků s PK. U paralelně pracující aplikace (což afaik je adrinkův případ) se mi neosvědčilo takové věci vyvádět moc často. V lepším případě to zpomaluje, v horším je MySQL schopná uhnít na deadlocku. Ale moje rada se nezakládá na takových detailech, ale naopak na tom že tyhle věci by se neměly řešit dokud to není opravdu nutné.
Poslední Tvé tvrzení IMHO není pravda (už proto, že na těch tabulkách mohou být pověšené triggery, on update current timestamp a podobná zvířátka)
Však proto taky píšu že to "může" být lepší tj. že je to potřeba změřit. AFAIK pokud to nebude dobře oklíčované tak by se stejně muselo seekovat. Optimalizaci tím že se nějaký kód _nenapíše_ bych ze všech vylomenin co tu padly považoval za nejmenší ztrátu času.
"2^24 comments ought to be enough for anyone" -- CmdrTaco
21.5.2012 21:17 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
S pravidlem: "nech to na db" bych souhlasil, jenže tvoje pravidlo tady tedy především není aplikovatelné: naopak bych spíše řekl, že řešení DELETE/INSERT je to nejjednodušší co je - dva jednoduše napsané dotazy (takže todle je strategie nechám to na databázi), zatímco selektivní smazání/úprava/vložení je na napsání daleko složitější (tak jaké nechej to na db?) a jeho vhodnost vyplývá ze znalosti chování databáze (zdali DELETE + INSERT je nebo není rychlejší než UPDATE).

(Navíc ani to pravidlo vždy neplatí: např. v postgresql jsou některé věci napsané jedním rekurzivním dotazem pomalejší, než totéž opsané PLPGSQL funkcí - např. získání kořene stromu - jestli si to teda pamatuju dobře)

--

Souhlasím, že se optimalizace a hrabání v DB zpravidla nevyplatí dělat, ale nikoli proto, že to databáze většinou udělá rychle: to může a nemusí platit, ale hlavně proto, že nejdražší je čas programátora a databáze to většinou udělá rozumně.

Optimalizace je na místě v okamžiku, kdy přestane stačit rychlost: a v tu chvíli je "nech to na databázi" sice dobrá heuristika, tzn. to, co člověk zkusí první a zpravidla bývá přinejmenším blízko k optimu, ale vyplatí se si otestovat pár řešení a vybrat si - a v tom, které možnosti vyzkoušet člověku často napoví znalost vnitřností DB.

--

Ohledně paralelní aplikace: jde o poměr čtení a zápisů: pokud při každém přihlášení uživatele by se měly všechny atributy přepisovat jen proto, že je třeba uložit login time, tak je to blbina. Pokud uživatele založej a jednou za půl roku mu něco změněj a zbytek provozu je čtení, pak se to vyplatí.

--

Ohledně zamykání bloků, tak to je jen dohad, vnitřnosti innoDB jsem detailně nezkoumal, ale co vím innodb má row-level locking a zamyká samotné řádky, nikoli datové stránky (pravděpodobně teda při úpravě dané stránky ji na danej okamžik zamkne, ale to je krátkodobej zámek, kterej by neměl vadit, pokud se spolu nepere n procesů chtějící měnit tu samou stránku; vaděj zámky přes celou transakci). Spolu s tím dělá intervalové zámky na B+stromem. Když se budou updatovat všechny vlastnosti daného uživatele, tak to prostě zamkne dané user_id - a to při změně uživatele jen dobře. Problém tam bude IMHO nikoli v zamykání nějakých bloků, ale v tom, že výmaz většího počtu záznamů může vyvolat štěpení stránek B+stromu indexů, což se bez dalšího zamykání neobejde a může to zasáhnout okolní uživatele.

--

Ohledně InnoDb a clusterování jiní píšou jinak - clusterovaný index v innodb je podle nich (i mne) redundantní B+strom, takže má v listech data, nejen klíč a odkaz na externí datové stránky. http://www.ovaistariq.net/521/understanding-innodb-clustered-indexes/ Koneckonců, kdyby v clustered indexu byl odkaz na data, proč by se měl jmenovat clustered? A proč by v ostatních indexech nemohl být ten samý odkaz, v Tvém řešení by při vyhledávání pomocí sekundárního indexu byl zbytečný seek na clustered index.

--

Poslední Tvé tvrzení nebylo, že to může být lepší, ale že většina databází zápis neměnící data ignoruje. :-) Což IMHO není pravda. Možná neodkládá starou verzi do logu (to nevím, tak hluboko jsem se v zdrojácích nevrtal), v každém případě musí řešit celou proceduru kolem načtení řádky, spouštění triggerů atd..., což má k ignoranci daleko.

rADOn avatar 22.5.2012 12:18 rADOn | skóre: 44 | blog: bloK | Praha
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
ad pravidlo "nech to na db"… DELETE+INSERT jsou jednoduché jen na počet písmen. DB ale nemůže uhádnout že po deletu přijde insert a že bude obsahovat tytéž řáďky. Prostě postavíš optimizeru do cesty betonovou zeď. S updatem může query optimizer přece jenom něco vykoumat. Když ne, je to jeho chyba, ne moje. Tomu říkám "nechat to na DB". I kdyby se nic jiného nedalo dělat, radši tam dám REPLACE v pevné víře že se to v budoucnu DB může naučit nějak optimalizovat. Když ne, o nic nepřicházím. A v neposlední řadě taky že tomu kdo to bude číst bude zřejmější vo co go.

--

ad zamykání – do pajšlu InnoDB taky moc nevidím, afaik co píšeš je přesně. Jenom doplním že při vkládání/mazání indexů to není úplně row locking a MySQL sahá i mimo. (Na detaily si už bohužel nevzpomenu, jenom že tam byla někdy v 5.x dokóděná výjimka aby se to nedělo při přidávání řádek na konec indexu. Předpokládám že v tu chvíli to přestalo trápit 90% lidí co mají autoincrementy a to byl konec pohádky :-) ) Pokud je to to čemu říkáš štěpení stránek B-stromu… není "výmaz většího počtu záznamů" náhodou přesně to o čem tu mluvíme? :-P

--

ad clusterovaný index – čtení dat z indexu není striktně vzato "clusterovaný index" ale rozumíme si. V listech jsou _pouze_ data toho indexu. Čili pokud máš index přes primární klíč, můžeš přečíst zase jen hodnotu PK a zbytek řádky musíš honit pěkně po disku :-) Samozřejmě na velkých datech si uděláš index přes ty sloupce který potřebuješ selectit, ale to je přesně ten typ optimalizace na který má tazatel ještě dost času takže bych to sem netahal. Dokonce právě naopak – pokud je to MySQL tak bych se takovým vylomeninám co nejdéle vyhýbal. Dokud se vejde do buffer poolu (a tazatel zmiňoval slabé statisíce řáďků :-) ) ničemu to valně nepomůže, leda snad tomu aby se tam nevešel.

--

ad neměnění nezměněných řádek… MySQL nemění. Přiznávám, jiný DB zase tolik neznám nebo jsem už zapoměl. A od doby co dělám na MySQL jsem si (kromě jiného) zvykl že když něco umí mysql, tak ostatní DB to umí taky a uměly to deset let před ní :-) Jestli je tohle výjimka tak má u mě Monty pivo.

--

S tím zbytkem naprosto souhlasím.
"2^24 comments ought to be enough for anyone" -- CmdrTaco
23.5.2012 04:17 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Ano - DELETE a INSERT je jednoduché na počet písmen a proto je i velká pravděpodobnost, že to bude to pravé. To je právě IMHO to nech to na db. Naopak Tvoje s updatem může query optimizer něco vykoumat není nech to na db: neboť to už předpokládá znalost vnitřností db, že tam je nějaký optimizer, že ten optimizer to umí zoptimalizovat, že to zoptimalizuje natolik dobře, že to vyváží nutnost místo dvou dotazů jich spustit N. Tomu rozhodně neříkám nech to na db, naopak to je technika, která staví na tom, že člověk tu databázi zná a ví, jak se chová.

Můžeš namítnout, že tvrzení, že čím méně dotazů (tzn. provádění změn "najednou") je optimální také spoléhá na nějakou znalost o db. Ano, to máš pravdu. Právě proto tvrdím, že pravidlo: "nech to na db" ve skutečnosti právě znamená: "napiš to tak nejjednodušejc (=nejméně písmenky a nejmenší mozkovou aktivitou), jak to jde." A teprv, pokud dotaz bude pomalej, tak to v případě nutnosti přepiš.

Samozřejmě, todle pravidlo je tak jednoduchý, až je blbý: čím víc člověk zná vnitřnosti DB, tím víc ho porušuje (vlastně už samotná normalizace je porušením tohoto pravdila). Ale zrovna v tomdle případě, kdy se střetávaj dvě protichůdná pravidla: (co nejmenší počet dotazů x co nejmenší manipulace s daty), kdy opravdu nejde výsledek jednoduše odhadnout a kdy to pravděpodobně bude záviset na charakteristice dat, se kterými se pracuje, toto pravidlo sedí jak .... na hrnec.

PS: (navíc to, že UPSERT bude rychlejší než DELETE a INSERT rozhodně není vina optimizeru, ten řeší plány a ty jsou tady zcela jasné a u obou přístupů stejné: najdi záznam(y) dle daného klíče. Ušetří se pouze některé činnosti kolem modifikací dat a indexů.

- Ad clustered index: Četl jsi ten odkaz? InnoDb používá na ukládání dat redundantní B+strom a tedy má v listech data, nikoli pouze PK. Pokud tomu nevěříš, tak si to přečti tady: http://dev.mysql.com/doc/innodb/1.1/en/innodb-create-index-implementation.html To, co popisuješ se týká pouze secondary indexů, ty samozřejmě data nedublujou. Jediný s čím souhlasím, že to pro rozhodnutí, jaké řešení zvolit, příliš relevanci nemá (ne že by to nemělo vliv, ale nevyplatí se to tkato do hloubky řešit, leda jako úlohu na procvičení vznitřností db).

-- Mysql je fakt nemění? Nojo, fakt. A to Ti jako přijde dobře? Když napíšu UPDATUJ tyto řádky, tak to snad chci, ne? Co si má co databáze vymýšlet, že něco neudělá, když ji napíšu, že to má udělat? To je horší než Windows :-) (píšu z Windows :-)). Co když má změnit ta data třeba až na tabulce pověšenej trigger? IMHO je to naopak chyba - pokud nechci, aby mi databáze neměnila data, který nepřepisuju, můžu si do UPDATE napsat podmínku.

No, když tak čtu co píšeš, tak MySQL toho opravdu v určitém ohledu umí hodně, co ostatní databáze ne. Nevím, jestli je ale opravdu o co stát.
23.5.2012 10:30 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Pokud chci aktualizovat záznam v databázi, slouží k tomu příkaz UPDATE a jeho použití je princip „nech to na databázi“. Pokud chci udělat aktualizaci záznamu, ale pro databázi to přeložím jako DELETE+INSERT, dělám něco za databázi, vycházím z nějakých předpokladů o znalosti databáze atd.
23.5.2012 14:43 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Jenže já nechci aktualizovat jeden záznam! Já mám hromadu záznamů, z nichž některé chci smazat, některé přidat a některé upravit. Ty říkáš, že je blbina rozdělit UPDATE na INSERT a DELETE. To máš pravdu. Jenže ty ho nerozdělíš za tu cenu, že rozdělíš dva dotazy na třeba třicet dotazů. A co je horší? A proč? Pokud člověk nic neví o vnitřnostech databáze, tak prostě nemá z čeho odvodit, že dva takovédle dotazy jsou horší než třicet makových.

Ty na to pohlížíš s předporozuměním, že přirozený způsob je udělat UPDATE a cokoli jiného je nestandardní způsob. Ale kde se tadle premisa vzala, když neřešíš, jak je databáze udělaná? Kdo a jak rozhoduje, co je standardní? Vem si databázi jako blackbox, nic o ní nevíš. A teď máš dva algoritmy, které provedou totéž. Jeden provede dva příkazy, druhý N příkazů. Odkud se bere tvrzení, že delší program je jednodušší?

Vzhledem k tomu, že oba algoritmy dělají totéž, tak komplexnější algoritmus evidentně předepisuje databázi PŘESNĚJI, jak má danou věc provést, tzn. nechává databázi méně prostoru pro volbu vhodného postupu. Tzn. postup nech to na databázi znamená: zvol co nejméně omezující program, tzn. co nejkratší.

--

Tvoje argumentace je podobná, jako kdybys řekl, že na nalezení nejmenšího prvku se používá klasický lineární průchod, takže je nejlepší data třídit algoritmem přímého výběru. A ono není. Nejde směšovat jednu operaci a balík operací.
23.5.2012 15:03 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Původní dotaz popisoval, jak uživatel upravuje některé záznamy. Aktualizace dat se v SQL zapisuje pomocí příkazu UPDATE. Všechno ostatní, co popisujete vy, jsou optimalizace, a je nesmysl dělat je dopředu. Na ně přijde řada, až zjistím, že zrovna tam je úzké místo, a pak musím zjišťovat, v čem je problém. Přičemž se rozhodně nebudu pokoušet optimalizovat podle délky příkazů a ani jen podle jejich počtu.
23.5.2012 16:29 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Chtěl jsem napsat dlouhý post, který Váš argument vyvracel z mnoha stran, ale nakonec jsem si uvědomil, že Váš post vychází z jednoduché premisy, která prostě není pravda. Pokud by tato operace bylo čisté update, proč by se to řešilo pomocí příkazu INSERT ... ON DUPLICATE .... Evidentně nejde o čistou update operaci a ze zadání to ani nevyplývá.

Zvolená operace je nejblíž operací nad nested table, jak je třeba možné dělat v Oracle. A tam jsou podporované obě sémantiky: jak selektivní úpravu jednotlivých řádků (čemuž odpovídá to INSERT ... UPDATE), nebo nahrazení obsahu tabulky novou sadou hodnot (tomu defakto odpovídá přístup DELETE + INSERT). Vzhledem k tomu, že v zadání byla editace celého seznamu, tak je na místě druhá možnost. Jak je vidět, přiklání se k tomu i tazatel.

Navíc: argument, že nejdražší čas je čas programátora a INSERT+DELETE se napíše nejjednodušeji jste nijak nevyvrátil. Ano, kdyby napsání třiceti dotazů INSERT+UPDATE (a pak ještě delete všech záznamů, které v seznamu nejsou, což není úplně jednoduchý dotaz a ani to nebude pro db zrovna nejlevnější) byla ta nejjednodušší cesta, jak to napsat, tak bych s Vámi souhlasil. Jenže tak to evidentně není.

Vy napíšete x-krát více kódu, nad kterým budete muset daleko více přemýšlet, jen proto, že máte dojem, že to databázi tak líp sedne (proč jinak byste ho prosazoval? protože se to tak dělá? to by byl přeci fanatismus.). Takže prosazujete, aby se udělala práce, která není nutná pro funkčnost programu, pouze pro jeho rychlost. Což je optimalizace.

PS: Ano, mé řešení je také optimalizací, ale optimalizací práce programátora. A tu smysl dělat má vždy. Teprv, kdyby se zjistilo, že ten INSERT+DELETE dělá problémy, tak je na místě řešení nějak optimalizovat na rychlost na úkor času programátora. Přesně jak píšete: dělat optimalizace dopředu je nesmysl. (navíc ta Vaše optimalizace není moc dobrá, když dělat optimalizace tak pořádně a přes tu temporary table, která spojí výhody obou řešení: zachová konstantní počet dotazů a přitom nebude dělat zbytečné změny v datových strukturách).

okbob avatar 23.5.2012 20:06 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
S tímhle nesouhlasím - prostě pro UPDATE záznamů je primárně UPDATE a měl by se použít. Kdokoliv, kdo tam najde DELETE/INSERT na to bude koukat jak jantar, a co ušetřil na čase autor, tak to stoprocentně ztratí editor, a stokrát prokleje autora za blafák.
23.5.2012 23:36 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Představ si celý kód: tam, co já vystačím s dvěma dotazy a jednoduchým cyklem skládajícím dohromady INSERT, musí bejt v případě UPDATE přístupu logika, která rozhoduje, co s danym řádkem vlastně dělat, jak poznat řádky, které jsou smazané atd... Za čas, co bude ten editor louskat, co ta logika vlastně dělá, tak má dávno přečtenou a pochopenou poznámku ve stylu: //Než řešit, které záznamy smazat upravit a vložit, radši vše smažu a vložím znova.

Ono ani není jasné, co a zda vůbec to je UPDATE. Pokud na řádce tři bylo 3.2. a teď je tam 1.2., tak je to změna, nebo je to smazání starého dne a dodání nového? Když je to tedy dle Tvého chápání změna, co když je ten 3.2. na další řádce? Atd....

Proto je podle mne chápání této operace ve smyslu nahrazení jedné množiny dní množinou jinou naprosto přirozené. A při nahrazování množin je přeci řešení, zdali náhodou ty dvě množiny nemají nějaké společné prvky, sice možná užitečná technika, ale rozhodně ne něco, co se prostě musí z principu udělat.

Samozřejmě, pokud to budu řešit AJAXem a opravdu online editací (reagující na změnu každého prvku), tak je řešení UPDATE na místě. Ale to je jinej případ.
25.5.2012 20:05 Matlák
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Jen plácnu do tohohle flejmu svůj názor - podle mě je nad větším množstvím dat rozhodně lepší si předem zjistit v každé jednotlivé situaci které řádky se budou updatovat a držet si to v paměti, než velké množství řádků mazat (pro desítky milionů řádků to může trvat veeelmi dlouho) a pak insertovat, nehledě na problémy s cizími klíči apod. Jasně že pokud záznamy co se mění nejsou provázány s jinými tabulkami a je jich relativně málo vzhledem ke kontextu, je lepší řádky smazat a insertovat, popřípadě (z hlediska poměru výkon/paměť asi nejvýhodnější) prostě jen insertovat (on duplicate key update). Pokud k tomu chcete mermomocí přidat mazání, je možné tabulku prostě po operaci "vyčistit" něčím co rozpozná nové (updated-inserted) řádky podle nějakého timestampu. Howghno.
rADOn avatar 23.5.2012 20:19 rADOn | skóre: 44 | blog: bloK | Praha
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Nejde o to že bys neměl pravdu ale jestli to máš vůbec řešit. Všechny ty syntaktické vývody které jsi tu popsal by měl ideálně udělat "automagicky" query optimizer. Pokud máš pravdu v tom že DELETE…INSERT je optimální způsob, pak by měl optimizer dojít ke stejnému závěru i z UPDATE a pod kapotou provést stejnou operaci. Jenže naopak to neplatí, DELETE…INSERT ztrácí informaci pro optimizer a tlačí ho k určitému chování. Naopak REPLACE možná pod kapotou dělá totéž, ale tu informaci neztrácí. V jednom případě je DB (možná) blbá, ve druhém ji nutíš udělat buď blbost nebo předčasnou optimalizaci.
Ano, mé řešení je také optimalizací, ale optimalizací práce programátora.
Pokud je programátor lama a neumí to napsat updatem, tak to není optimalizace času ale optimalizace na kreténa. Sorry. "Předčasná optimalizace" je pro mě snaha vnucovat DB nějaké specifiké chování, ne to že člověk neumí napsat standartní dotaz. Všechno co tu padlo (DELETE…INSERT, INSERT…ON DUPLICATE KEY…, UPDATE, REPLACE) považuji z hlediská kompetentního programátora za samozřejmé nebo snadno dohledatelné. A pro nekompetentního není ztráta času se to naučit.
Vy napíšete x-krát více kódu, nad kterým budete muset daleko více přemýšlet, jen proto, že máte dojem, že to databázi tak líp sedne (proč jinak byste ho prosazoval? protože se to tak dělá? to by byl přeci fanatismus.).
Ne, my nad tím nebudeme dumat a napíšeme dotaz tak jak nejlépe vystihuje náš záměr a spolehneme se že si s tím magický stroječek poradí. Můžeš tomu říkat fanatismus :-) Psát kód je snadné, zkoumat co s ním ta mrcha provádí a ovlivňovat to je těžké.
"2^24 comments ought to be enough for anyone" -- CmdrTaco
23.5.2012 23:13 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Jenže z toho update k tomu delete vše/insert ten optimizer prostě dojít nemůže, protože neví, že já takhle postupně oedituju všechny řádky. To je právě ten princip! Že v SQL není cesta, jak říci databázi, co chci udělat, v jednom příkazu. Buďto ztratím informaci o tom, že některé záznamy z balíku pouze upravuji, nebo o tom, že pracuji s balíkem. Obé uchovat nejde. Tak nechápu, proč preferovat jeden fakt před druhým.

Optimalizace je práce navíc, kterou dělám proto, aby kód běžel rychleji. Je jednodušší napsat jedno DELETE a pak jeden INSERT, nebo cyklus přes všechny dotazy, u každého vytvořit složitější INSERT ON DUPLICATE UPDATE dotaz a jako třešničku na dortu DELETE pro odstranění řádek, které jsem změnil? A budete kvůli tomu načítat staré řádky z databáze, abyste zjistily, které to byly, nebo si to nějak pamatovat ve formuláři, nebo bude na konci jeden dotaz, ve kterém bude hrozivá NOT IN podmínka přes všechny nové záznamy? - už jen fakt, že je třeba todle vymyslet hovoří o tom, o kolik je to složitější řešení...

Takže si stojím za tím, že je to optimalizace, protože to není nejrychlejší způsob, jak to napsat, takže práce navíc, kterou děláte kvůli výkonu - ergo kladívko optimalizace. Nebo to neděláte takto kvůli výkonu? Tak proč?

Pokud někdo tvrdíte, že Vaše řešení je podobně složité jako moje INSERT+DELETE, schválně ho napište. Já napíšu své a porovnáme, čí kód je kratší a jednodušší.
25.5.2012 22:01 Matlák
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Mno, řekl bych že tohle už je moc. Velmi záleží na tom co s daty děláte a kolik jich je. Pokud má tabulka půl milionu řádků a uživatel interakcí s nějakým formulářem posílá řekněme 50 řádků v jedné operaci, může být výhodnější udělat DELETE+INSERT s tím, že řádky (posílané formulářem) logicky nesmí mít v žádném případě vazby cizími klíči na jiné, právě needitované tabulky. V takovém případě je to jednoduché na pohled, rychlé a (mimo tančící autoinkrement sloupce) v podstatě správné.

Pokud má tabulka řekněme 50 milionů řádků a uživatel pošle během jedné operace uploadováním datového souboru 100 tisíc řádků u kterých je několik jednotek či desítek tisíc změněných, je rozhodně výhodnější použít selektivně update. Parser vstupního souboru pak běží většinu času "naprázdno" a s db komunikuje jenom když ji potřebuje ;-)
23.5.2012 20:53 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Nevím, o jaké operaci píšete vy. Já píšu o zadání, kde stojí napsáno: "Ked si user edituje dni". Tam není nic o INSERT ... ON DUPPLICATE ..., tam je "uživatel edituje", nebo-li uživatel upravuje, což se v SQL zapisuje jako UPDATE. Dokonce si to i dovedu živě představit - uživatel dostane nějakou tabulku na způsob Excelu, tam má některé řádky vyplněné a upravuje je, případně může některé řádky smazat a přidat na konec nové. Úpravy řádků jsou UPDATE, mazání DELETE, přidávání INSERT. Když to takhle implementujete, bude to hezky fungovat. Když se pokusíte místo UPDATE použít DELETE+INSERT a nedomyslíte to, budou si uživatelé stěžovat, že to občas dělá hlouposti. V drtivé většině případů to v tom "Excelu" uživatel nebude dělat metodou DELETE+INSERT, protože to neodpovídá způsobu, jakým lidé pracují.

Nevím, jak jste přišel na to, že operace DELETE+INSERT bude jednodušší na naprogramování. Od uživatele dostanete sadu změn, sadu smazaných řádků a sadu přidaných řádků, takže když z toho chcete udělat váš DELETE+INSERT, musíte každou tu změnu převést na dva příkazy. To není zjednodušení.
23.5.2012 23:27 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
A nedomyslíte to? Co nedomyslím? Co nebude fungovat? Konkrétně?

Od uživatele nedostanu sadu změn, od něj třeba dostanu sadu zaškrtanejch políček, který to budou dni. Nebo sadu políček z webovýho formuláře, ve kterým mám vyplněný dni. Pokud chci dostat co smazal, co vložil nově atd., tak je to informace navíc, jejíž získání musím naprogramovat. Nevím, proč bych se s tím měl štvát. Takže ano, Vaše implementace bude hezky fungovat, ale ta moje taky, jen bude napsaná o půl dne dřív.

A já nikde nepíšu o DELETE+INSERT na každej řádek, asi si od začátku bohužel nepochopil celou diskusi. Já říkám, že pro první implementaci je nejjednodušší řešení udělat jeden DELETE na všechny dni daného usera a pak jeden INSERT se všema dny daného usera. A pokud to nebude výkonnostně stačit, tak pak je správná cesta novou sadu dní nasypat do temptable a pak provést opět pouze dva dotazy (DELETE WHERE NOT IN temptable; INSERT INTO dni SELECT FROM temptable WHERE NOT IN dni *) Že je má strategie dobrá ukazuje i to, že pro zoptimalizování do IMHO pro DB nejlepšího řešení stačí velmi malá úprava.

Vůbec se nebudu štvát s jednotlivejma řádkama, nějakym sledováním, co uživatel s kterou řádkou udělal - ono by to taky mohlo vyústit v to, že uživatel jeden řádek smaže, takže se dni posunou o jedno, a já budu jak blbec editovat všechny řádky apod.

*) To v MySQL teda nejde, podmínka na tu samou tabulku, takže v Mysql holt udělám o dotaz víc
24.5.2012 08:06 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Nedomyslíte třeba způsob identifikace záznamů a smažete i takové, které uživatel nesmazal. Třeba uděláte přesně tu chybu, jak jste to popsal ve vašem komentáři – smažete všechny záznamy uživatele. Takže uživateli zobrazíte 3 záznamy, on je upraví. Mezi tím někdo vloží pro daného uživatele 4 záznam. První uživatel změny odešle, vy smažete všechny 4 záznamy a vložíte 3 nové. Právě jste uživateli kvůli chybě smazal jeden záznam a vysloužil jste si u uživatelů pověst tvůrce aplikace, která občas ztrácí nějaká data. A to vám to ještě dalo víc práce.

Uživateli se zobrazí třeba webová stránka s tabulkou, kde bude editovat údaje.
ID  Sloupec 1 Sloupec 2
1      A         X        smazat
2      B         Y        smazat
3      A         Z        smazat
                          přidat
Uživatel tabulku zedituje
ID  Sloupec 1 Sloupec 2
1      A         Q        
2      C         L        
3                         smazáno
       D         L
       A         F                          
Data projedete a triviálně poznáte, co je UPDATE, co DELETE a co INSERT. Vy byste pak musel UPDATE překládat na dva příkazy DELETE+INSERT.
24.5.2012 12:07 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Právě, že naopak: pokud uživatel edituje nějaké své termíny, tak očekává, že to, co potvrdí, tak bude uloženo. Daleko horší, než že se ignoruje nějaká úprava dat, ale data v aplikaci jsou uživatelem potvrzená a zkontrolovaná verze, než když dva lidi zadají nějaký vstup a výsledkem je nějaký (alespoň pro uživatele) nepředvídaný mix z nich, který nikdo nepotvrdil, že je správně. Vaše řešení bude totiž také přemazávat některé konkurentní vstupy, moje to alespoň udělá předvídatelně a vždy stejně - ne že některé současné editace ponechá a některé zahodí. Pokud chcete race condition vyloučit, tak se stejně nějaké implementaci časových razítek nevyhnete.

Modelovej případ - typická situace: stejnou změnu zadají dva lidi najednou, jen každej trochu jinak.
Původní sada   Editace A     Editace B
C                A             C 
D                C             A 
                 E             E
čí algoritmus bude mít v db na konci očekávaná data? Výsledek AADD mi teda jako terno fakt nepřijde. (tomu se částečně vyhnete, pokud budete updatovat všechny záznamy, nikoli pouze editací změněná - pak ovšem zase ztratíte všechny update, které provedla aktualizace A, takže z aktualizací ABCZ a EFGZ se stane EFGCZZ - opět horší výsledek než EFGZ mého algoritmu - uřivatel B chtěl evidetnně C odstranit).

--

Tak znova: já to řeším pomocí JEDNOHO update a JEDNOHO delete, NIKOLI překládat KAŽDEJ update na jeden insert a jeden delete. To samozřejmě smysl moc nemá. Už to došlo? Proč furt polemizujete s něčim, co netvrdím.

Jasně, já vím, jak to budete dělat. Jen tvrdím, že je to řádově složitější, než řešení s jedním delete a jedním insertem. Protože já ani nemusím nic projíždět a poznávat, ani nemusím řešit jak to vlastně poznávat. Pokud nesouhlasíte, tak opakuji: napište to. Bez nějakých syntaktických kontrol a takovejdlech "drobností", čistě logiku. Ale nezapomeňte do toho zahrnout případnou logiku, která musí být na straně formuláře: tzn. jak vlastně budete rozlišovat, která políčka pocházejí z databáze a která jsou nová. Já to napíšu také a porovnáme.

24.5.2012 12:11 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
přeznačil jsem kvůli druhému příkladu písmenka a nedal jsem si pozor, výsledek bude AAEE, ale to je snad jasný.

24.5.2012 12:28 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Dosaďte si za ty vaše sady, nějaký vstup apod. něco konkrétního. Třeba faktury. Opravdu uživatelé očekávají, že přidají fakturu, uloží, a za deset minut nebude po faktuře ani památky, protože někdo jiný si otevřel seznam faktur před přidáním faktury a beze změny jej uložil po přidání?

Váš modelový případ je nesmysl od začátku do konce. Mimo jiné proto, že nevíte, co je sada, co znamená editace, co znamená A, C, D atd.

Když uživatel upraví 5 záznamů, já udělám:
UPDATE table SET … WHERE id = 5 AND version = 1;
UPDATE table SET … WHERE id = 13 AND version = 2;
UPDATE table SET … WHERE id = 24 AND version = 1;
UPDATE table SET … WHERE id = 7 AND version = 1;
UPDATE table SET … WHERE id = 8 AND version = 1;
Vy uděláte
DELETE FROM table WHERE id = 5 AND version = 1;
INSERT INTO table VALUES (5, 2, …);
DELETE FROM table WHERE id = 13 AND version = 2;
INSERT INTO table VALUES (13, 3, …);
DELETE FROM table WHERE id = 24 AND version = 1;
INSERT INTO table VALUES (24, 2, …);
DELETE FROM table WHERE id = 7 AND version = 1;
INSERT INTO table VALUES (7, 2, …);
DELETE FROM table WHERE id = 8 AND version = 1;
INSERT INTO table VALUES (8, 2, …);
Před tím budete ještě muset vypínat kontrolu cizích klíčů. Je to sice dál, zato horší cesta.
24.5.2012 13:08 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Tady je s odpuštěním někdo natvrdlej. Tak znova. Já NEEEEEEEEBBBBBBBUUUUUUUUUDDDDDDUUUUUUU záznamy zpracovávat po jednom. To je důvod, proč to takto řeším.
DELETE FROM tabulka WHERE userid = ?
INSERT INTO tabulka() VALUES (),(),() ...
Jak už to mám jinak napsat? Mám pocit, že mluvím do dubu. (úplně pominu, že jsi zcela vynechal to, že jsi ze svého řešení napsal tu snadnou část, ale to, proč je to řešení složité: tzn. jak budeš evidovat nové řádky a smazané řádky a jak je budeš editovat si nenapsal.)

Ano, pokud by to bylo určeno k editaci faktur, na kterých jsou cizími klíči pověšené další záznamy, tak můj algoritmus nebude vhodný. Jenže jaksi tady se nebavíme o fakturách. Zadání bylo jasné: seznam dní, žádná závislá data. Ano, kladivo se nehodí na šroubování.

(Navíc na faktury se nehodí ani ten Váš algoritmus, protože ani on neřeší race condition: u editace faktur se to prostě musí řešit s jejich naprostým vyloučením, a to nesplňuje ani jeden algoritmus. Mám pocit, že vůbec nečteš co píšu a jen vymýšlíš nějaké hypotetické blbiny nesouvisející ani s dotazem tazatele, ani s tím, co píšu, jen aby sis ospravedlnil své řešení.).
24.5.2012 13:15 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Takže smažete i něco, co se smazat nemělo. Na to už jsem vás několikrát upozorňoval.
Zadání bylo jasné: seznam dní, žádná závislá data.
Tohle v zadání nebylo. Vy navíc předpokládáte další podmínky – třeba jednouživatelský přístup nebo to, že záznamů bude málo a nebude potřeba stránkování. Jakmile některá z těchto podmínek přestane platit (což v reálném projektu bude nejpozději za týden), můžete vaše řešení zahodit a udělat to celé znova způsobem, který popisuju.
24.5.2012 13:43 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
I ten delete může mít v IN navíc podmínky na konkrétní ID, kdybych to chtěl řešit - ale ono to má spíše více nevýhod, než výhod (viz můj post -2). Opakuješ své argumenty dokola, aniž bys reagoval na jejich vyvrácení.

Tvůj algoritmus také maže to, co nemá, a naopak nemaže to co má, můj to akorát dělá konzistentněji. Pokud chceš zaručit zachování vstupů, nějakému explicitnímu řešení race condition se nevyhneš. Což je podstatou mého postu -2, na který nijak nereaguješ, jen dokolečka opakuješ to, co jsi už třikrát napsal a co jsem Ti rozporoval.

V zadání žádná závislá data zmíněna nebyla a jak z povahy dat tak i z toho, že tazatel uvažuje tento algoritmus implicitně vyplývá, že tam prostě nejsou. Pokud by byla, tak jde o jinou úlohu - např. by pravděpodobně se taková data needitovala "na hromadě", ale po jednom.

Opět nad tím přemýšlíš, aniž bys uvažoval o jaká data jde. Jde o dni, takže pokud jich bude více, budou zobrazena např. po měsících, čtvrtletích, v každém případě to bude seřazený interval, takže opět mám jednoduchý způsob, jak smazat vše v daném balíku.
24.5.2012 13:51 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
I ten delete může mít v IN navíc podmínky na konkrétní ID, kdybych to chtěl řešit
Na tom tolik nezáleží. Navíc když chcete použít optimistické zamykání a řádky verzovat, musela by databáze podporovat IN pro vektory.
Opakuješ své argumenty dokola, aniž bys reagoval na jejich vyvrácení.
Nic jste nevyvrátil. Akorát jste navrhl alternativní řešení, které je složitější a nefunguje.
Tvůj algoritmus také maže to, co nemá, a naopak nemaže to co má
Například?
Jde o dni, takže pokud jich bude více, budou zobrazena např. po měsících, čtvrtletích, v každém případě to bude seřazený interval, takže opět mám jednoduchý způsob, jak smazat vše v daném balíku.
Akorát budete muset pro každý pohled znovu navrhovat dotaz. Bude chtít vedoucí upravovat záznamy všech podřízených? Nový dotaz. Bude chtít někdo zobrazení za pracovní dny, za svátky? Další dva dotazy. Přičemž víceuživatelský přístup jste stále nevyřešil.
24.5.2012 14:10 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Multihodnotové IN normálně databáze podporují, i kdyby ne, verzování jde udělat s jednoznačným identifikátorem (číslo verze přeci mohou všechny záznamy sdílet), a navíc kde je v zadání nějaké verzování (které jde navíc udělat x způsoby, nejen tím jedním, jak předpokládáš).

Dokázal jsem Vám na reálném příkladě, že Vaše řešení se taktéž není schopno vyrovnat s konkurenčními úpravami tak, aby výsledek byl očekávaný (mimochodem, ono to ani z principu nejde - z principu prostě nezle určit, jestli současná změna jedné řádky má mít za výsledek jednu nebo dvě řádky), takže Tvůj argument je neopodstatněný. Psal jsem o tom celý jeden post i s příklady, v předchozím jsem na něj opět odkazoval. Opakovat to nebudu, aspoň scrollovat snad umíš, prosím, zkus alespoň číst, co píšu, je to fakt s odpuštěním jak diskuse s dubem.

Jaký nový dotaz? Použiju vždy stejnou podmínku, kterou stejně musím napsat pro zobrazení patřičných záznamů z databáze. Akorát místo SELECT tam dám DELETE. To musím vysvětlovat každou blbinu?
24.5.2012 14:38 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Multihodnotové IN normálně databáze podporují
Databáze normálně možná, MySQL pokud vím ne.
číslo verze přeci mohou všechny záznamy sdílet
No to bude báječné, takže kdokoli udělá nějakou změnu, všem ostatním tím způsobí konflikt.
kde je v zadání nějaké verzování
Je to klasický způsob, jak řešit optimistické zamykání.
Dokázal jsem Vám na reálném příkladě
Nedokázal. Napsal jste nějaký zmatený příklad, který by v praxi vůbec nebylo možné realizovat.
mimochodem, ono to ani z principu nejde - z principu prostě nezle určit, jestli současná změna jedné řádky má mít za výsledek jednu nebo dvě řádky
Ale jde to. Protože změna údajů v řádku a přidání řádku jsou dvě různé operace jak z hlediska uživatele, tak z hlediska databáze. Ze změny se tedy nikdy nemůže stát přidání. Zkuste si to třeba v Excelu – úprava řádku a přidání řádku jsou dvě různé operace.
24.5.2012 15:01 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Uč se :-)

CREATE TEMPORARY TABLE a(a integer, b integer);
INSERT INTO a VALUES ( 1, 2 ) , ( 3, 4 ) , (5,6);
SELECT * FROM a WHERE (a, b) IN (( 3, 4 ), (5,6))

Sdílet, tzn. sdílet jednu sekvenci. Omlouvám se, že to nevysvětluji dosti polopatě, furt marně předpokládám, že než něco napíšeš, tak se nad tím zamyslíš.

Jenže uživatel, pokud chce jeden záznam smazat a jeden přidat, tak prostě ten "k smazání" změní na ten novej. A aplikace nemá šanci poznat, jestli to je úprava termínu (tzn. dvě takové konkurenční úpravy mají furt modifikovat jeden záznam), nebo jestli je to přidání nového a smazání starého (tzn. další úprava toho pole má generovat další záznam).
Ono to není jasné ani v realitě: když se jedna schůzka zruší a místo toho se svolá na příští týden, jde o stejnou schůzku, jen přesunutou, nebo o jinou schůzku? Když navrhuješ aplikaci, nemůžeš se na to dívat jako programátor s jasně vymezenjma kolonkama: INSERT, UPDATE. Musíš myslet jako normální lidi.

To byla jedna chyba tvého algoritmu. Druhá chyba je v tom, že současné přidání jednoho záznamu dvěma lidmi tento záznam dabluje. A poslední chyba je, že když uživatel B něco smaže, ale těsně před tím to tam uživatel B vloží (např. jen proto, že to tam bylo, ale on vloží nějakou hodnotu mezi dvě jiné, takže všem datům se změní IDčka a toto jako poslední bude nově vložené), tak přestože to A chtěl smazat a editoval poslední, tzn. má být smazáno, tak to v db zůstalo.

Zmatený příklad který nelze realizovat? Jako proč? To, že něco nechápete ještě neznamená, že to nejde realizovat. Pokud nerozumíte mému zápisu, klidně se zeptejte na konkrétní věc, co znamená, rád vysvětlím. A pokud tvrdíte, že tato posloupnost operací nelze realizovat, tak doložte proč. Napsat, že je něco blbost bez sebemenšího odůvodnění umí každý, ale ve slušné diskusi se neodůvodněné argumenty nepoužívají, takže na to radši nebudu blíže reagovat.
24.5.2012 15:46 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Sdílet, tzn. sdílet jednu sekvenci. Omlouvám se, že to nevysvětluji dosti polopatě, furt marně předpokládám, že než něco napíšeš, tak se nad tím zamyslíš.
Nápodobně. Popište s tou vaší sdílenou sekvencí dva případy s tabulkou, která má dva řádky. V prvním případě jeden uživatel upraví jeden záznam, ve druhém případě první uživatel upraví jeden záznam a druhý uživatel druhý záznam. Jak se změní verze?
Jenže uživatel, pokud chce jeden záznam smazat a jeden přidat, tak prostě ten "k smazání" změní na ten novej. A aplikace nemá šanci poznat, jestli to je úprava termínu (tzn. dvě takové konkurenční úpravy mají furt modifikovat jeden záznam), nebo jestli je to přidání nového a smazání starého (tzn. další úprava toho pole má generovat další záznam). Ono to není jasné ani v realitě: když se jedna schůzka zruší a místo toho se svolá na příští týden, jde o stejnou schůzku, jen přesunutou, nebo o jinou schůzku? Když navrhuješ aplikaci, nemůžeš se na to dívat jako programátor s jasně vymezenjma kolonkama: INSERT, UPDATE. Musíš myslet jako normální lidi.
Výhoda právě je, že uživatel buď upraví jeden záznam, nebo jeden záznam zruší a druhý přidá. Takže nemusíte nad ničím spekulovat, a prostě v databázi uděláte přesně to, co udělal uživatel. Když uživatel v kalendáři bafne čtvereček myší a přesune ho, je to úprava, když na něj klikne, zmáčkne Delete, je to smazání, když dá "Přidat událost", je to přidání. Jak prosté.
To byla jedna chyba tvého algoritmu.
To nebyla chyba mého algoritmu, nýbrž vaše minutí se s reálným světem.
Druhá chyba je v tom, že současné přidání jednoho záznamu dvěma lidmi tento záznam dabluje.
To není chyba. Když dva lidé přidají po jednom záznamu, je jediný správný výsledek přidání dvou záznamů. Můžete si to vyzkoušet - když do prázdné kasičky přidáte jednu korunu a někdo druhý tam pak přidá další korunu, musí tam být na konci dvě koruny. Když tam najdete jen jednu korunu, máte vadnou kasičku.
A poslední chyba je, že když uživatel B něco smaže, ale těsně před tím to tam uživatel B vloží (např. jen proto, že to tam bylo, ale on vloží nějakou hodnotu mezi dvě jiné, takže všem datům se změní IDčka a toto jako poslední bude nově vložené), tak přestože to A chtěl smazat a editoval poslední, tzn. má být smazáno, tak to v db zůstalo.
Uživatel A nemůže mazat záznam, který v databázi ještě není. Uživatel B nemůže do databáze vložit záznam, který už tam je.
takže všem datům se změní IDčka
IDčka se nemění. Kdyby se měnila, nebyla by to IDčka.
Zmatený příklad který nelze realizovat? Jako proč?
Protože ten příklad je jenom míchání písmenek. Za ta písmenka nejde dosadit nic z reálného světa ani nic z databáze reprezentující reálný svět. Reálný svět se vyznačuje například tím, že každý objekt existuje právě jednou, takže třeba když držíte minci a dáváte ji do kasičky, nemůže někdo jiný tutéž minci zároveň z kasičky vyndavat. V databázi se totéž reprezentuje pomocí primárních klíčů, typicky IDček, která reprezentují daný objekt.
24.5.2012 17:36 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Jak by se změnila verze - každému novému či změněnému záznamu se jako číslo verze přiřadí další číslo ze sekvence. Při změně se zjistí, zdali číslo verze v db se shoduje s číslem verze z formuláře. Jestli je tam problém, tak prosím vysvětlit, nějak furt nechápu, kde ho vidíš?

Jenže uživatel není programátor a takhle prostě nemyslí. Ten to tam prostě nějak nabouchá a čeká, že to bude fungovat. Ať už to přesune, smaže a znovu založí, nebo třeba odstraní všechny termíny a znovu tam opíše svůj diář. Jenže ono to fungovat nebude, protože udělal něco, co programátor ve svý hantýrce nazývá UPDATE a ne INSERT či naopak. Za takovýdle aplikace uživatelé vražděj: ty chtěj, ať se aplikace chová vždycky stejně. Nějakej race condition je jim někde, oni prostě chtěj, ať co při stisku tlačítka odeslat v seznamu je, aby to tam bylo a co tam neni, aby to tam nebylo. A ne, aby se to chovalo různě podle toho, jestli ten seznam upravovali tak nebo jinak.

Ad koruny: Kladivo se nehodí ke šroubování. Koruny nejsou dni. Když dva lidi napíšou, že člověk přišel ten den do práce, tak to znamená, že tam přišel dvakrát?? To dosvědčuje mj. i to, že pro "důkaz" používáš úplně jinej příklad, než o kterém se bavíme - protože v našem případě by podobnej příklad ztratil smysl. Převody peněz bych řešil jinak, ale todle nejsou převody peněz. Už jen proto, že převody peněz je multiset, zatímco todle je set.

Znovu a polopatě: v databázi je záznam A. Přijde uživatel změní ho na B, pak si ale uvědomí, že vůbec nechtěl A smazat, že to bylo omylem, že chtěl jen přidat B. Tak za to ještě dopíše A. Tzn. Ačku se změní Idčko. (Nebo to tak udělá proto, že postupně po řádcích do programu opisuje termíny z diáře.) Jenže v tu chvíli jiný uživatel v současné editaci to A smaže. Ale ouha, ono tam to A furt je. Můžeš desetkrát tvrdit, že to ten uživatel udělal špatně, ale takhle se v realitě užívaci chovaj a pokud to nebudeš ve svejch aplikacích respektovat, tak je to Tvoje chyba. Aplikace je pro uživatele, ne naopak. Uživatel nic neví o tom, že záznam má nějaký idčko nebo co je to insert a delete, uživatel prostě změní data a očekává, že jsou změněná.

Pokud tvrdíš, že za písmenka nejde nic dosadit, tak prosím nefušuj do programování. Protože programování není o ničem jiném než o reprezentaci reality písmenky. K tomu fakt už není co dodat, pokud si pod těma písmenkama neumíš představit třeba záznam že dne 1.A. přišel někdo do práce.

PS: Jinak v reálném světě samozřejmě nejde dát jedna mince dvakrát do jedné kasičky (aniž bys ji vyňal), ale krásně jde dvakrát do programu naťukat, že sem dal jednu minci dvakrát do jedné kasičky. A Tvuj program se s tím musí umět vyrovnat a takovéto chyby (ani ne chyby, tady prostě race condition: dva lidé vidí, že to tam ještě není, tak to tam dopíšou) odstraňovat. A ten Tvůj algoritmus toho prostě není schopnej. Můj také ne, ale narozdíl od Tvého se alespoň pro uživatele chová očekávatelněji a netvrdí o sobě, že to řeší.
24.5.2012 19:21 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Jak by se změnila verze - každému novému či změněnému záznamu se jako číslo verze přiřadí další číslo ze sekvence. Při změně se zjistí, zdali číslo verze v db se shoduje s číslem verze z formuláře. Jestli je tam problém, tak prosím vysvětlit, nějak furt nechápu, kde ho vidíš?
U mne problém není. Problém je ve vašem řešení hromadného smazání, protože tam s žádným porovnáním čísla verze nepočítáte.
Jenže uživatel není programátor a takhle prostě nemyslí. Ten to tam prostě nějak nabouchá a čeká, že to bude fungovat.
A ono to funguje, protože ty programy fungují tak, jak jsem popsal. Vyzkoušejte si to -- zkuste třeba OpenOffice.org Calc, MS Outlook kalendář, Google Calendar, MS Excel, MS Access, OpenOffice.org Base, jakékoli účetnictví, evidenci knih, správu blogu, e-shopy...
Když dva lidi napíšou, že člověk přišel ten den do práce, tak to znamená, že tam přišel dvakrát?
Když člověk nemůže přijít dvakrát za den do práce, nemá to jít do databáze zadat. Což se zařídí třeba tak, že na dvojici člověk-den udělá unikátní index. Pokud pak někdo zadá druhý příchod ve stejném dni, aplikace ho upozorní na chybu - tedy v mém řešení. Ve vašem chybu zazdí a předchozí záznam smaže.
Znovu a polopatě: v databázi je záznam A. Přijde uživatel změní ho na B, pak si ale uvědomí, že vůbec nechtěl A smazat, že to bylo omylem, že chtěl jen přidat B. Tak za to ještě dopíše A. Tzn. Ačku se změní Idčko. (Nebo to tak udělá proto, že postupně po řádcích do programu opisuje termíny z diáře.) Jenže v tu chvíli jiný uživatel v současné editaci to A smaže. Ale ouha, ono tam to A furt je. Můžeš desetkrát tvrdit, že to ten uživatel udělal špatně, ale takhle se v realitě užívaci chovaj a pokud to nebudeš ve svejch aplikacích respektovat, tak je to Tvoje chyba. Aplikace je pro uživatele, ne naopak. Uživatel nic neví o tom, že záznam má nějaký idčko nebo co je to insert a delete, uživatel prostě změní data a očekává, že jsou změněná.
Mně to nevysvětlujte, já jsem vám to psal už několik komentářů zpět, že vám tam chybí verzování záznamů. Když už jste na to taky sám přišel, tak si to konečně opravte.
Pokud tvrdíš, že za písmenka nejde nic dosadit, tak prosím nefušuj do programování. Protože programování není o ničem jiném než o reprezentaci reality písmenky. K tomu fakt už není co dodat, pokud si pod těma písmenkama neumíš představit třeba záznam že dne 1.A. přišel někdo do práce.
Místo těch hloupých řečí byste konečně mohl napsat, co tedy ta písmenka znamenají. Primární klíč? Nebo snad pro identifikaci dat používáte něco jiného, než primární klíč?
Jinak v reálném světě samozřejmě nejde dát jedna mince dvakrát do jedné kasičky (aniž bys ji vyňal), ale krásně jde dvakrát do programu naťukat, že sem dal jednu minci dvakrát do jedné kasičky. A Tvuj program se s tím musí umět vyrovnat a takovéto chyby (ani ne chyby, tady prostě race condition: dva lidé vidí, že to tam ještě není, tak to tam dopíšou) odstraňovat. A ten Tvůj algoritmus toho prostě není schopnej. Můj také ne, ale narozdíl od Tvého se alespoň pro uživatele chová očekávatelněji a netvrdí o sobě, že to řeší.
Ale kdepak. Můj algoritmus této chybě zabrání. To jenom váš algoritmus z toho udělá guláš.
24.5.2012 20:43 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
U mě problém není.
Je - ale nev algoritmu. Celá tadle subdebata se vede, protože si netušil, že Mysql umí multihodnotové IN, nevěděl jsi, jak implementovat verzování pomocí jedný sdílený sekvence:
... Jak se změní verze?
...a tvrdil jsi, že to verzování bude nějak působit nějaké konflikty.
No to bude báječné, takže kdokoli udělá nějakou změnu, všem ostatním tím způsobí konflikt.

Jestli to tedy už netvrdíš (co takhle uznat omyl?), tak ok, tak je jasné, že verzování jde dělat v obou algoritmech(v mém přístupu není problém zkontrolovat, že všechny mazané mají správnou verzi). Jelikož i Tvůj algoritmus bez verzování se nechová v multiuser prostředí dobře (viz dál) a v obou jde verzování snadno implementovat, pak nemá smysl se o verzování bavit. Proto ho také můj algoritmus neobsahoval - narozdíl od Tebe se snažím soustředit na princip.

To, že se Tvůj algoritmus bez verzování chová špatně jsem doložil na příkladech, že je nejsi schopen pochopit nebo i vymyslet sám, můj problém není (omlouvám se za sarkasmus, ale to fakt už nejde).

To že tvrdíš, že když mistr i jeho zástupce napíšou dělníkovi najednou presenci, tak že je správně, že ji má dvakrát, s tím se holt polemizovat nedá. Holt jen počítej, že když takovou aplikaci napíšeš, tak Ti ten mistr dá přes hubu, až mu to bude např. blbě počítat přesčasy.

Co ty písmenka znamenají? Umíš číst? Vždyť to v minulym postu píšu. Prosím už po desáté, alespoň zkus číst co jsem napsal. Tak znova: Můžeš si pod každým písmenkem např. představit datum, kdy byl daný užívák v práci. A ano, normální člověk v životě používá většinou pro identifikaci něco jiného, než primární klíč - u data např. právě to datum. To, že záznam nějakej PK má, uživatele vůbec netrápí a právě proto je CHYBA očekávat, že bude rozlišovat mezi přepsáním data a smazáním + vytvořením nového: protože tyto operace se liší právě pouze tím, jaké má výsledný záznam PK. Pokud se tedy aplikace v těchto případech chová odlišně, tak budou uživatelé na aplikaci nadávat. A Tvůj algoritmus se právě (mj.) v těchto případech (bez verzování, viz výš) nekonzistentně chová.

PS: Tvůj výkřik s vyjmenováním padesáti programů, kdy každej má multiuser konkurenci vyřešenou lépe či hůře různými algoritmy (často i pštrosem) pak komentovat vůbec nebudu, nevím, co tím chtěl básník říci.

A pokud Ti nestačí soupis chyb, tak tady máš další: A nějaký záznam smaže a potom B ten samý záznam (browser si otevřel před potvrzením transakce A) změní, tak ten záznam stejně zmizí Přitom B provedl akci později a tak by tam měl zůstat záznam B. A třeba zrovna toto neodstraní ani Tebou navržené verzování.

PPS: Btw. - ono ani s verzováním z PRINCIPU nelze problém současné editace vyřešit. Jestli nechápeš proč, tak se zamysli, proč v databázích existuje izolace transakcí SERIALIZABLE, která právě tento problém řeší, a proč transakce na této úrovni izolace nejsou zaručeně proveditelné (tzn. mohou být zaříznuté, že nejdou serializovat).
24.5.2012 21:12 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Celá tadle subdebata se vede, protože si netušil, že Mysql umí multihodnotové IN
Zda to umí nebo neumí je nepodstatný implementační detail. Když to nemá popsané v dokumentaci operátoru IN, je celkem logické myslet si, že to neumí.
nevěděl jsi, jak implementovat verzování pomocí jedný sdílený sekvence
Nevěděl jsem, jak to udělat funkčně. Vaše nefunkční řešení mne nezajímá.
a tvrdil jsi, že to verzování bude nějak působit nějaké konflikty.
Standardní verzování jednotlivých řádků, které jsem použil, problémy způsobovat nebude. Problémy bude způsobovat vaše neverzování.
Jestli to tedy už netvrdíš (co takhle uznat omyl?), tak ok, tak je jasné, že verzování jde dělat v obou algoritmech(v mém přístupu není problém zkontrolovat, že všechny mazané mají správnou verzi). Jelikož i Tvůj algoritmus bez verzování se nechová v multiuser prostředí dobře (viz dál) a v obou jde verzování snadno implementovat, pak nemá smysl se o verzování bavit. Proto ho také můj algoritmus neobsahoval - narozdíl od Tebe se snažím soustředit na princip.
O čem to píšete? Já jsem navrhl nějaký algoritmus s verzováním, který funguje. Vy jste navrhl algoritmus bez verzování, který nefunguje. Pak jste ho různě měnil a vycházely vám z toho nefunkční verze, až když jste jej konečně změnil na ten, který jsem já popsal hned na začátku, začalo vám to fungovat.
To že tvrdíš, že když mistr i jeho zástupce napíšou dělníkovi najednou presenci, tak že je správně, že ji má dvakrát
To se v mém algoritmu neděje. To jen ten váš vyrábí v databázi hlouposti.
Můžeš si pod každým písmenkem např. představit datum, kdy byl daný užívák v práci.
V tom případě si tam nejdříve doplňte primární klíče, ať se máme o čem bavit.
A ano, normální člověk v životě používá většinou pro identifikaci něco jiného, než primární klíč - u data např. právě to datum.
Normální člověk ovšem nemá problém poznat, co je jeden objekt, a co jiný, a je si jist tím, zda jsou to dva objekty nebo jeden. Dokáže ty objekty identifikovat - a primární klíč je jen způsob, jak tu identifikaci vyjádřit v databázi.
To, že záznam nějakej PK má, uživatele vůbec netrápí a právě proto je CHYBA očekávat, že bude rozlišovat mezi přepsáním data a smazáním + vytvořením nového: protože tyto operace se liší právě pouze tím, jaké má výsledný záznam PK.
Chyba to není, každý normální člověk takhle přemýšlí. I malé dítě ve školce pozná rozdíl v tom, jestli mu jedno jablko vezmete a dáte mu místo něj jiné, nebo jestli do jednoho jablka kousnete.
A Tvůj algoritmus se právě (mj.) v těchto případech (bez verzování, viz výš) nekonzistentně chová.
Můj algoritmus ale verzování má.
Tvůj výkřik s vyjmenováním padesáti programů, kdy každej má multiuser konkurenci vyřešenou lépe či hůře různými algoritmy (často i pštrosem) pak komentovat vůbec nebudu, nevím, co tím chtěl básník říci.
To je dobře, že to nekomentujete, protože já jsem nic takového nenapsal. Pocit, že někdo v této diskusi neumí číst, máte správný. Bohužel vás ale musím zklamat, že tím dotyčným jste vy. Zkuste si přečíst ještě jednou, na co jsem reagoval.
A pokud Ti nestačí soupis chyb, tak tady máš další: A nějaký záznam smaže a potom B ten samý záznam (browser si otevřel před potvrzením transakce A) změní, tak ten záznam stejně zmizí
Nezmizí. B bude upozorněn, že někdo mezi tím změnil data, a dostane na výběr, jak konflikt vyřešit.
Btw. - ono ani s verzováním z PRINCIPU nelze problém současné editace vyřešit. Jestli nechápeš proč, tak se zamysli, proč v databázích existuje izolace transakcí SERIALIZABLE, která právě tento problém řeší, a proč transakce na této úrovni izolace nejsou zaručeně proveditelné (tzn. mohou být zaříznuté, že nejdou serializovat).
Od někoho, kdo do teď nepochopil, jak optimistické zamykání s verzováním řádků funguje, to je opravdu vtipný komentář. Až to pochopíte, pochopíte taky, proč verzování řádků zabrání skrytému ztrácení změn.
25.5.2012 01:09 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Nemám sílu se vyjadřovat ke každý polopravdě a blbině.

Můj algoritmus verzování má... Krásně překrucuješ svoje stanovisko. Na začátku byla debata o tom, zdali je správné použít DELETE+INSERT nebo UPDATE. Ty jsi začal tvrdit, že můj algoritmus je špatně, protože nemá odolnost proti konkurenčním updatům (což v požadavcích nebylo). S verzováním jsi přišel až na upozornění, že to sice jo, ale furt to řeší líp, než postup který jsi navrhoval místo toho.

Přitom do obou postupů jde ochrana proti konkurenčním updatům snadno dodat, takže to je argument v debatě, jestli UPDATE po záznamech nebo INSERT+DELETE irelevantní. Takže je to podobnej argument jako: mercedes je lepší než audi, protože je modrej.

--

Ano: správně zabezpečenej verzovací algoritmus detekuje konflikty. To bohužel Tvůj jaks ho zatím prezentoval není, protože tam (alespoň v tom, co jsi napsal) nikde nekotroluješ, kolik ovlivnil UPDATE řádků. Takže žádný konflikt nehlásíš. (ale máš pravdu v tom, že nic jiného než hlásit konflikt nemůžeš, vyřešit to automaticky nelze). Nicméně dejmetomu, že to doplníš. Pak to sice furt nebude fungovat, přestože to tvrdíš:
To se v mém algoritmu neděje.
...protože kde tam kontroluješ, zdali daná hodnota v databázi je či ne? Nikde. Takže co zabrání tomu, když mistr a jeho zástupce najednou vložej do databáze stejnej den, aby se tam vložil?

Dobře, řekněme, že opravíš i to. Pak je otázka -- jde i v přístupu s DELETE+INSERT zabezpečit podobně jednoduchým způsobem alespoň stejně tak dobře konzistenci? Aniž by jeden zápis (jak jsi také tvrdil) zablokoval celou databázi? Vzhledem k tomu, že tvrdíš
To jen ten váš vyrábí v databázi hlouposti.
tak seš furt přesvědčenej, že ne. Dobře. Tak Ti dám poslední šanci. Zamysli se nad tím a napiš, jestli jde napsat. Pokud furt ne, tak Ti to verzování tady předvedu -- ale Ty uznáš, žes pitomec, žes tvrdil, že to nejde. Ooook? A já klidně uznám, že jsem pitomec, pokud takovej algoritmus napsat nedokážu. Oook? Jdeš do toho, nebo stáhneš ocas a uznáš omyl?
Normální člověk ovšem nemá problém poznat, co je jeden objekt, a co jiný, a je si jist tím, zda jsou to dva objekty nebo jeden
Ano, normální člověk třeba pozná, že schůzka 24.8. je schůzka 24.8. A pokud se mu program chová jednou tak a jednou jinak, protože té jedné samé schůzce nějakej blbej programátor jednou přiřadil id 1 a jednou přiřadil id 2, protože z nějakýho důvodu byl záznam o ní ze systému vymazán a znovu vložen Id je umělej identifikátor a rozhodně nevyjadřuje identitu objektů: není žádnou výjimkou, když ten samej objekt má v databázi postupně jiná ID, protože člověk záznam o něm několikrát do databáze vložil a zase smazal. Jestli je Id něčeho identifikátor, tak ZÁZNAMU O OBJEKTU. A programátor, kterej nutí uživatele, aby místo o OBJEKTU přemešleli o ZÁZNAMU O OBJEKTU je s odpuštěním vůl, protože jeho aplikace jsou neergonomický.

PS: Tvůj příklad s kousnutým jabkem je opět demagogie, protože když vymažu a znovu vložím ten samý záznam, tak uživatel nemá šanci poznat, že byl smazán. U kousnutého jabka bys to poznal snad i Ty :-) (sorry, nedalo mi).

PPS: V příkladech je id záznamu určeno jeho pozicí, jak si jde snadno odvodit z výsledků dotazu.

Řešení 1× (l0gik)
25.5.2012 08:40 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Váš algoritmus verzování nemá, hromadný DELETE bez podmínky na jednotlivá ID nejde s verzováním rozumně použít. Odolnost proti konkurenčním updatům považuju za samozřejmou, to není žádná extra vlastnost navíc, kterou by bylo potřeba v zadání zmiňovat. S verzováním jsem počítal od začátku, proto mne taky ani nenapadlo navrhovat nějaký algoritmus s hromadným mazáním.

Postupy jsou tu tři. UPDATE, hromadný DELETE + INSERTy a DELETE+INSERT po jednotlivých záznamech. Vy mezi druhým a třetím řešením volně přepínáte -- když tvrdíte, že to řešení umí verzování, mluvíte o třetím případu, když o tom, že je to méně operací, mluvíte o druhém. Pokud už jste tedy dospěl k tomu, že druhý algoritmus nejde použít a je potřeba použít třetí, uvědomte si, že tam aktualizaci každého řádku přepisujete z UPDATEu na dva příkazy DELETE+INSERT. A zamyslete se nad tím, zda a k čemu je takový přepis užitečný.

Detekce počtu ovlivněných řádků logicky není ve výpisu SQL příkazů uvedena, protože ji dělá aplikace. Není potřeba to explicitně psát, protože každý, kdo má aspoň základní zkušenost s databázemi a někdy optimistické zamykání s verzováním záznamů psal ví, jak to bude vypadat.

Fungovat to bude. Pokud si myslíte, že ne, napište nějaký příklad, kdy to fungovat nebude. Při tom prosím nezapomeňte na unikátní indexy, jako se vám to stalo v předchozím příspěvku.

V přístupu, kdy jeden UPDATE nahradíte dvojicí DELETE+INSERT konzistenci samozřejmě zaručit lze, protože když ty dva příkazy uzavřete do izolované transakce a v databázi nebudou na těchto záznamech žádné závislosti, bude výsledek identický, jako s jednoduchým UPDATEm (to ale neplatí o způsob provedení). Akorát jste nevysvětlil, jaký smysl by mělo nahradit jeden příkaz dvěma a skrýt před databází informaci, kterou by mohla použít pro optimalizaci.

Ano, pořád jsem přesvědčený, že nejde napsat algoritmus, který bude používat hromadný DELETE (ne podle primárního klíče), který bude verzovat jednotlivé záznamy, nebude porovnávat obsah záznamu a nebude hlásit falešné poplachy (tj. konflikt na řádku, který nikdo neupravil). Problém totiž není v tom verzování (tam se dá použít sdílená sekvence nebo čas změny záznamu), ale v tom hromadném mazání. To totiž smaže a znovu vytvoří (= nová verze) i záznamy, které uživatel nijak nezměnil.

Normální člověk nepozná, že schůzka 24.8. je schůzka 24.8. Normální člověk před sebou vidí kalendář, kde má barevné obdélníčky, a ty znamenají schůzky. Na 24.8. může mít v kalendáři x různých schůzek. Normální člověk taky ví, že když ten obdélníček bafne myší a přetáhne jinam, změní se datum a čas schůzky, ale bude to pořád tatáž schůzka (a zůstanou u ní informace jako kancelář, pozvaní lidé, poznámky apod.). Zatímco když tu schůzku smaže a vytvoří jinou, bude to jiná schůzka, která s původní nebude mít nic společného. A bude tam muset znovu zadat kancelář, pozvané kolegy, poznámku, popis…

Váš příklad se smazáním a vložením toho samého záznamu platí jen v případě, kdy daná tabulka nemá žádné vazby. Což je případ velmi ojedinělý – a je pak otázka, proč vůbec chcete používat SQL databázi.

Dobře, v příkladu je id záznamu určeno pozicí. Takže si to převedeme na něco reálného – na začátku mám v bedýnce 1 cibuli a v bedýnce 2 datle. Pak přijde Adam, z bedýnky 1 vysype cibuli a dá tam ananas, z bedýnky 2 vysype datle a dá tam cibuli a přidá bedýnku 3, do které dá estragon. Zároveň přijde Bára, z bedýnky 2 vysype datle a dá tam ananas a přidá bedýnku 3, do která dá estragon. Když se to pokusí udělat druhý z nich, dojde ke konfliktu v bedýnkách 1 a 2, který bude muset vyřešit. Takže Adam nebo Bára rozhodnou o tom, která varianta je správně – zda A, C, E nebo C, A, E.
25.5.2012 15:24 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Nezapomeňte na unikátní indexy. Tady tě bohužel zklamu, protože jsem na ně nezapoměl. Ale pokud dotaz na tom vkládání selže na unikátní index, tak to není správné chování, protože uživateli vyhodíš chybu (a ve většině databází sletí celá transakce), přičemž tento konflikt je v případě datové struktury set, o kterou jde, řešitelný automaticky.

Hele - a netrpíš samomluvou? Protože se tady hádáš sám se sebou. Já nikdy netvrdil, že nebudu potřebovat podmínky na verzi, jen že se to dá napsat jedním dotazem. Stejně tak Tvé tvrzení že můj algoritmus verzování nemá není pravdivý. Můj algoritmus má verzování jako možnost a když bude potřeba, tak se napíše, když ne tak ne - stejně jako ty tvrdíš, že ta oprava těch X chyb, co jsem našel v Tvém algoritmu je jen něco, cos tam nenapsal. Buď férovej.

Stejnětak není pravda, že jsem někdy uvažoval DELETE+INSERT po jednom, to je pouze Tvá utkvělá představa, kterou Ti každý druhý post vyvracím, vyrvracím a vyvracím a přesto máš furt utkvělou představu, že to chci dělat. To už je s prominutím na psychiatra. Další Tvoje tvrzení: ano jsem přesvědčen, že algoritmus... neexistuje. Proč tam dáváš padesát milionů podmínek, které jsem nikdy netvrdil, že můj algoritmus splňuje? Opět to polemizuješ sám se sebou. (mj. hromadný delete jde i podle id, pokud tam doplním druhou intervalovou podmínku, tak to bude řádově efektivnější než X samostatných delete) "Kdy tabulka nemá zpětné vazby, což je příklad ojedinělý." Tady se snažíš dokázat že máš pravdu tím, že změníš zadání: my tady prostě závislá data nemáme (pokud ano, musel bys považovat autora dotazu za idiota, že vůbec DELETE+INSERT uvažuje - což vzhledem k tomu jak diskutuješ Ti asi nedělá problém? Tak co, považuješ autora dotazu za idiota?).

Ty prostě místo toho, aby jsi se pořádně zamyslel nad tím, jaké je zadání a co píšou ostatní, tak sis vymyslel nějaký algoritmus a prosazuješ ho jako jedinou možnost. A ostatní možnosti odmítneš tím, že buďto překroutíš zadání, nebo překroutíš jejich řešení. Pokud Ti to pomůže k tomu, že se cítíš jako king...

--

A protože furt píšeš, že můj algoritmus nejde použít, tak prosím:

DELETE FROM tabulka WHERE podminka AND verze NOT IN (...id_verze...) 
if(počet smazaných < počet editovaných) then ROLLBACK
INSERT INTO tabulka() VALUES (data)
Problém s tím, že mažu všechno je Tvoje typická výtka: vůbec sis totiž neuvědomil, že přesně totéž dělá Tvůj algoritmus? Copak ty také neděláš update na všechny záznamy?, takže všem neměníš verzi? Nikde v Tvém algoritmu podmínku, na to, že selektíš z DB původní hodnoty a porovnáváš nevidím. Nebo je to další zamlčená fíčura, takže si hraješ na to, jak máš jednoduchý algoritmus, ale to jen proto, že Ti kolem každýho update schází dalších deset podmínek? Pokud to je tak - opět: i já mohu stejně detekovat nezměněné záznamy a z hromadných operací je explicitně vyloučit, čím se to liší? Asi tím, že ten Tvůj algoritmus jsi psal Ty a tak tam se to samzořejmě předpokládá, zatímco když totéž nenapíše někdo jinej, je blb, že? Porovnávej srovnatelné: primitivní přístup X primitivním, verzování X verzování a verzování s porovnáním dat X verzování s porovnáním dat. Opakuji: v tomto threadu šlo o to, zdali je lepší přístup po řádcích, nebo dávkový, pokud chceš dokázat, že mercedes je lepší než audi, protože hele, naložím ho do letadla a lítá, tak si posluž, ale prosím příště na to upozorni předem, abych věděl, že debata nemá cenu.

Todle totiž principiálně nejde řešit bez operací, která porovnává data a modifikuje jen opravdu změněné záznamy. (Akorát já, protože to dělám v dávce, tak budu mít možnost ošetřit situaci, kdy člověk dva záznamy vymění (tzn. defakto přehodí primární klíče). Jelikož uživatel o PK nic neví (tzn. např. pořadí dat dané PK nenese žádnou informaci) tak by tato operace neměla mít na výsledek algoritmu vliv.)

--

Ad 28.4. - Pokud to bude model, kdy je možno více schůzek jeden den, pak ovšem musí být ty schůzky rozlišené a tedy jde opět o jiný případ než co řešíme zde: je-li datum klíč, pak v našem případě jde o implementaci datové struktury set, zatímco v tamté multiset. A světe div se, různé datové struktury se upravují různými algoritmy. Jinými slovy, další příklad, kde jsi upravil zadání, abys dokázal svoji pravdu.
Řešení 1× (l0gik)
25.5.2012 16:04 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Pokud se uživatel pokusí vložit duplicitní záznam do unikátního indexu, je správné oznámit mu chybu a nechat jej problém vyřešit. Pokud by to byla datová struktura set, bude unikátní index zároveň primárním klíčem, použiju SQL příkaz REPLACE a je to vyřešené automaticky.
Já nikdy netvrdil, že nebudu potřebovat podmínky na verzi, jen že se to dá napsat jedním dotazem. … Stejnětak není pravda, že jsem někdy uvažoval DELETE+INSERT po jednom
Poslyšte, nemohl byste si vybrat. Takhle se popřít hned v následujícím odstavci, to není hezké. Takže – budete záznamy mazat hromadným DELETEm s podmínkou bez IDček, nebo je budete mazat po jednom, tj. v podmínce budou IDčka?
jen že se to dá napsat jedním dotazem
No a co? To nikoho nezajímá.
stejně jako ty tvrdíš, že ta oprava těch X chyb, co jsem našel v Tvém algoritmu
X = 0
mj. hromadný delete jde i podle id
V tom případě netuším, co si představujete pod hromadným DELETEm. Já si pod tím představuju právě to, že podmínka popisuje množinu záznamů podle dat, ne podle primárních klíčů. Když to uděláte podle primárních klíčů, je to přesně to rozepsání každého UPDATU na dvojici DELETE+INSERT.
pokud tam doplním druhou intervalovou podmínku, tak to bude řádově efektivnější než X samostatných delete
Pokud k DELETE podle ID doplníte druhou podmínku, bude to nanejvýš pomalejší, než DELETE jen podle IDček.
Tady se snažíš dokázat že máš pravdu tím, že změníš zadání: my tady prostě závislá data nemáme (pokud ano, musel bys považovat autora dotazu za idiota, že vůbec DELETE+INSERT uvažuje - což vzhledem k tomu jak diskutuješ Ti asi nedělá problém? Tak co, považuješ autora dotazu za idiota?).
Proč teda každý záznam v databázi má unikátní ID? Pokud má jít jen o tabulku, která pro uživatele eviduje seznam dnů, stačí dvojice uživatel+den, to celé v primárním klíči. Navíc pak je to obyčejná množina (set), která má jen operace přidání a smazání, aktualizace nemá smysl řešit.
Ty prostě místo toho, aby jsi se pořádně zamyslel nad tím, jaké je zadání a co píšou ostatní
Já jsem se zamyslel. Ale takhle se nezamyslet, jak se to podařilo vám – nepochopit zadání, práci uživatelů, algoritmy ani sám sebe – to se jen tak někomu nepovede.
DELETE FROM tabulka WHERE podminka AND verze NOT IN (...id_verze...)
Co je id_verze?
if(počet smazaných < počet editovaných) then ROLLBACK
Takže pokud uživatel upraví 100 záznamů a v 1 bude konflikt, hodíte mu zpátky na hlavu 100 záznamů, ať si ten konflikt najde ručně? To budete dostávat tisíce děkovných dopisů…
A protože furt píšeš, že můj algoritmus nejde použít, tak prosím:
Dobře. Uživatel ukládá tyto změny:
smazáno:
id=1, verze=1
id=3, verze=2
upraveno:
id=2, verze=1, datum=A
id=4, verze=2, datum=B
přidáno:
datum=C
datum=D
Jak bude vypadat posloupnost SQL příkazů, které zavoláte? Jak budete testovat návratové hodnoty (počty změněných řádků)? Ideálně když to popíšete jako v předchozím komentáři v nějakém pseudoPL/SQL, ale s dosazenými hodnotami parametrů.
Copak ty také neděláš update na všechny záznamy?
Proč bych to dělal? Dělám update na ty záznamy, které uživatel upravil. Neupravené záznamy ani uživatel nikam neodesílá, bylo by to jen plýtvání.
Opakuji: v tomto threadu šlo o to, zdali je lepší přístup po řádcích, nebo dávkový
Už jste si rozmyslel, který přístup zastáváte? V druhém odstavci jste byl pro přístup podle IDček (po řádcích), ve třetím pro dávkový…
Todle totiž principiálně nejde řešit bez operací, která porovnává data a modifikuje jen opravdu změněné záznamy.
Změněné záznamy se poznají podle toho, že je uživatel změnil. Tedy přepsal nějakou hodnotu a potvrdil ji, otevřel editační režim a uložil změny nebo něco takového. Koukáním na výpis se záznamy nemění.
Ad 28.4. - Pokud to bude model, kdy je možno více schůzek jeden den, pak ovšem musí být ty schůzky rozlišené a tedy jde opět o jiný případ než co řešíme zde: je-li datum klíč, pak v našem případě jde o implementaci datové struktury set, zatímco v tamté multiset. A světe div se, různé datové struktury se upravují různými algoritmy. Jinými slovy, další příklad, kde jsi upravil zadání, abys dokázal svoji pravdu.
Pokud jde o datovou strukturu set, bude unikátní index na dvojici uživatel, datum. Ale hlavně, uživatel nebude mít žádnou možnost upravovat, jenom přidávat a mazat. Protože v datové struktuře set nikdo nic upravovat nechce, a normální člověk si ani nepředstaví, co by to znamenalo.
25.5.2012 17:46 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Hromadný/dávkový způsob je, že napíšu jeden příkaz a ono to něco udělá s hromadou záznamů. Přečti si na wiki definici dávkového zpracování: "všechna data jsou připravena předem a pak se vykoná program". Nikde není napsáno, že to znamená, že se se všemi záznamy provádí stejná operace, nebo jak jsou záznamy, nad kterými je provedena dávka identifikované. Pro debatu o odborné problematice to chce znát terminologii.
Když to uděláte podle primárních klíčů, je to přesně to rozepsání každého UPDATU na dvojici DELETE+INSERT
Není, protože relační databáze jsou dělané na hromadné změny dat. Zapsáním do jednoho dotazu se ušetří spousta času, protože velká část činností se bude muset dělat jen jednou (parsování dotazu, optimalizace, zamykání datových struktur etc...) a navíc bude moci databáze zvolit optimální plán na získání těch záznamů, než když se to dělá po jednom, čímž se dostáváme k další věci, ve které nemáš pravdu.

Pokud mám delete where id IN (...) a pak delete where id in () and něco between něco and něco, tak je druhý dotaz může být (dle rozložení dat a statistik) rychlejší, protože je intervalový. Tzn. v prvním dotazu databáze neví, které jsou a pro každý udělá extra lookup do indexu. Pokud bude těch idček hodně, tak dokonce zvolí sekvenční přístup nebo nějaký hash-join. Pokud tam ovšem bude druhá intervalová podmínka tak si místo toho databáze může jedním dotazem do indexu zjistit patřičné bloky a v nich pak už jen sekvenčně zkontrolovat idčka. Pokud nevěříš, tak si to zkus na nějakejch rozumnejch datech udělat explain plánů, že jsou opravdu jiné, což ukazuje na to, že pro databázi je výhodnější to hledat dle té intervalové podmínky. Samozřejmě závisí na tom, jak velkou část z toho intervalu chci: ale to je přesně to "nech to na db".

--

Proč má záznam v databázi unikátní ID? Třeba proto, aby byl jednoduchý primární klíč. A ze spousty jiných důvodů (např. standardní zpracování ORM nástroji či nástroji na generování dotazů atd. atd.). Navíc: já jsem někde psal, že tam musím mít idčka? To, že tam musím mít idčka je opět vaše projekce. Zas polemizujete sám se sebou.
Takže pokud uživatel upraví 100 záznamů a v 1 bude konflikt, hodíte mu zpátky na hlavu 100 záznamů, ať si ten konflikt najde ručně? To budete dostávat tisíce děkovných dopisů…
Ano, hodím. Napíšu mu: v databázi se stala oproti editaci taková a taková změna (to vyslektím opět jedním dotazem), tyto dni zmizely, tyto se objevili. Opravdu chcete vložit těchto sto záznamů a ostatní smazat? Když uživatel pracuje s množinou záznamů, tak je neslušné ho nechat půlku množiny uložit a půlku ne. Je na něm, jestli bude řešit jen ten konflikt, nebo na ten konflikt zareaguje úpravou celé množiny, proč mám být chytřejší než on.
Co je id_verze?
To už jsem psal? To musím každou věc napsat desetkrát? Id verze je id verze, tzn. číslo, které se po každé změně mění a je unikátní v db. Tedy např. je na tabulce before insert or update trigger NEW.id_verze = nextval('table_verze_seq')
Ale hlavně, uživatel nebude mít žádnou možnost upravovat, jenom přidávat a mazat
Takže jen kvůli tomu, abych dostál svému programovacímu purismu, že něco je set, tak místo toho, aby když se člověk při zadávání splete, tak danou položku přepsal, tak ji musí smazat a nahrát jinou. Ještě že nevyvíjíš aplikace pro mě.
/příklad/
Tak zaprvé jsem psal, že budu mít id verze sdílené, takže ten příklad nevyhovuje. Ale to je detail, protože
Neupravené záznamy ani uživatel nikam neodesílá, bylo by to jen plýtvání.
...jste totálně překroutil zadání. Vždyť tazatel přímo píše: "ale bolo by to podla mna narocnejsie kazdy jeden zaznam skontrolovat a nasledne updatovat alebo neupdatovat.". Takže dle zadání NEVÍTE, co bylo nebo nebylo upraveno, smazáno atd uživatel odesílá celou množinu a pokud to chcete vědět, musel byste to u každého záznamu zjistit (= skontrolovat, neumíte-li slovensky). Holt když celá vaše kritika vyplývá z toho, že si ani neumíte pořádně přečíst zadání....

25.5.2012 19:58 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Děkuji za tři odstavce nesouvisejících plků o hromadném zpracování. Pro naši debatu je podstatné něco, co jste opominul. Někdy navrhujete jeden způsob zpracování, pro jednoduchost ho nazývám dávkový - záznamy se vyberou nějakou podmínkou na data (např. ID uživatele), a ty se všechny smažou. V tomto případě nemůžete použít verzování jednotlivých záznamů. Druhý způsob zpracování nazývám po větách. Záznamy jsou určeny IDčky, která budou v podmínce příkazu. Není moc velký rozdíl z hlediska výkonu databáze v tom, zda to bude jeden příkaz s podmínkou IN, nebo zda to bude jeden předkompilovaný příkaz s podmínkou ID=, který se v jedné transakci zavolá opakovaně pro různá data. Schopnější databáze stejně v obou případech provede to samé. V tomto případě můžete použít verzování řádků, a při použití podmínky s ID= dokonce rovnou zjistíte, které záznamy mají konfliktní změnu.
Navíc: já jsem někde psal, že tam musím mít idčka? To, že tam musím mít idčka je opět vaše projekce.
Pořád se tu oháníte dotazem, že je potřeba se do puntíku držet toho, co je tam napsáno, neuvažovat nic víc ani nic míň. Tak si to tam dohledejte.
To už jsem psal? To musím každou věc napsat desetkrát? Id verze je id verze, tzn. číslo, které se po každé změně mění a je unikátní v db. Tedy např. je na tabulce before insert or update trigger NEW.id_verze = nextval('table_verze_seq')
Nechal jsem se unést těmi rádobyodbornými kecy, co tu máte (a které se vždy nakonec ukážou jako nesmysl), a předpokládal jsem, že jste se do toho příkladu pokusil napsat něco použitelného. Dobře, takže id_verze se přiřazuje ze sekvence pro celou tabulku při každém vytvoření a aktualizaci záznamu. Vzhledem k tomu, že záznamy vůbec nechcete aktualizovat, ale vždy mazat a vkládat znova, je to vlastně druhý primární klíč tabulky. Takže ho s dovolením můžeme škrtnout a nahradit primárním klíčem ze sekvence a zákazem updatu nad tabulkou. Takže váš příkaz můžeme nahradit za DELETE ... WHERE podminka AND id NOT IN (). To pro databázi není zrovna šťastný dotaz, pokud nebudete mít složený index, bude muset načíst všechny záznamy podle podmínky, donačíst k nim IDčka z dat a ty pak proskenovat. Přitom ale víme, že podmínce vyhovovali v době načtení dat uživateli právě ty záznamy, jejichž IDčka máme. Takže dotaz můžeme změnit na DELETE ... WHERE ID IN(). Ušetříme tím práci databázi (dostane rovnou IDčka, která si s vaším příkladem musela teprve donačíst), zpřehlednili jsme dotaz, a navíc máme univerzální příkaz, který můžeme použít pro všechny editační pohledy (nemusíme si pamatovat podmínku editačního pohledu). Nechci se chlubit, ale tenhle opravený dotaz jsem použil hned na začátku, protože je to polovina toho DELETE+INSERT.
Takže jen kvůli tomu, abych dostál svému programovacímu purismu, že něco je set, tak místo toho, aby když se člověk při zadávání splete, tak danou položku přepsal, tak ji musí smazat a nahrát jinou.
Můžete mi prozradit, jak konkrétně si to UI představujete? Já bych třeba kalendářní data volil klikáním a tažením myši v kalendáři. Jak si představujete tu úpravu? To jako když kliknu omylem na 5.6.2012, vyvolám tam nějak editační režim, přepíšu datum na 7.6.2012 a uložím? Nebylo by milionkrát jednodušší a zažité kliknout na 5.6.2012 znovu, čímž se záznam ze setu vymaže, a pak kliknout na 7.6.2012, čímž se tam přidá nový záznam?
...jste totálně překroutil zadání. Vždyť tazatel přímo píše: "ale bolo by to podla mna narocnejsie kazdy jeden zaznam skontrolovat a nasledne updatovat alebo neupdatovat.". Takže dle zadání NEVÍTE, co bylo nebo nebylo upraveno, smazáno atd uživatel odesílá celou množinu a pokud to chcete vědět, musel byste to u každého záznamu zjistit (= skontrolovat, neumíte-li slovensky). Holt když celá vaše kritika vyplývá z toho, že si ani neumíte pořádně přečíst zadání....
V zadání není nic o tom, zda vím, co bylo či nebylo upraveno. Když se chcete tak přesně držet zadání, tak buďte důsledný. Za druhé, pokud někdo umí perfektně formulovat zadání, v drtivé většině případů zná i odpověď. Spousta (ne-li většina) dotazů v této poradně spočívá v tom za tazatele nebo spolu s ním pořádně naformulovat zadání.
25.5.2012 21:40 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Není rozdíl? Cože? To jako fakt chceš tvrdit, že udělat něco jedním nebo deseti dotazy je pro výkonnost databáze jedno? Tak si prosím zkus např. v postgresql spustit následující kód, přičemž změř čas posledních dvou dotazů. Pokud by tvé tvrzení bylo pravdivé, měli by dosahovat podobných časů.

CREATE TEMPORARY TABLE bench (a integer primary key, b integer);
CREATE INDEX i ON bench(b);

DO LANGUAGE PLPGSQL $$
DECLARE R integer;
BEGIN
FOR R IN SELECT generate_series(1,10000) LOOP
   INSERT INTO bench(a,b) VALUES 
                    (r*20, r*1000);
END LOOP;
END $$;
analyze bench;

DO LANGUAGE PLPGSQL $$
DECLARE R integer;
BEGIN
FOR R IN SELECT generate_series(1,4000) LOOP
   INSERT INTO bench(a,b) VALUES 
		(r*20+1 ,r+1),(r*20+2 ,r+2),
		(r*20+3 ,r+3),(r*20+4 ,r+4),
		(r*20+5 ,r+5),(r*20+6 ,r+6),
		(r*20+7 ,r+7),(r*20+8 ,r+8),
		(r*20+9 ,r+9),(r*20+10 ,r+10);
   DELETE FROM bench WHERE a IN (r*20+1,r*20+2,r*20+3,r*20+4,r*20+5,r*20+6,r*20+7,r*20+8,r*20+9,r*20+10) AND b between r+1 and r+19;
END LOOP;
END;
$$;

DO LANGUAGE PLPGSQL $$
DECLARE R integer;
 S integer;
BEGIN
FOR R IN SELECT generate_series(1,4000) LOOP
   FOR S IN SELECT generate_series(1,10) LOOP
	   INSERT INTO bench(a,b) VALUES (r*20+s, r+s);
   END LOOP;
   FOR S IN SELECT generate_series(1,10) LOOP
	   DELETE FROM bench WHERE a=r*20+s;
   END LOOP;  
END LOOP;
END;
$$;
Na mém systému je to rozdíl 0.181s ku 0.620s. Tvůj "není rozdíl" je ve skutečnosti více než trojnásobný (což na pouhých deset dotazů je dost). A to ještě navíc tady je ten dotaz opravdu předkompilovaný, jak píšeš, což ovšem při normálním webovém programování nikdo nedělá a je to další práce navíc; a také odpadá komunikace s databází, což je další nezanedbatelná položka (a to nemluvím o případu, kdy databázovej stroj běží někde jinde na síti).
V zadání není nic o tom, zda vím, co bylo či nebylo upraveno.
Autor dotazu tvrdí, že pokud by chtěl dělat nějakou aktivitu v závislosti na tom, jestli by byl daný řádek upraven, musel by to skontrolovat. Z toho si domyslí i průměrná opice, že to tedy neví, proč by vyvíjel nějakou aktivitu na zjištění skutečnosti, kterou zná? Nevykrucuj se.

Jak by vypadalo UI je mi někde, je dané zadání, tak řeším zadání a ne své dojmy. Např. třeba jako textbox se všema dny (na opisování z nějakého výkazu IMHO naprosto ideální UI, pro člověka, co to používá denně daleko rychlejší než nějaký klikací blbiny).
...donačíst k nim IDčka...
Co kdybys už konečně přestal vymešlet teorie a aspoň něco z toho, co tvrdíš, si zkusil. Aspoň bych tu nemusel vyvracet každou blbinu. Do příkazu výše si dodej na konec následující příkazy:
DO LANGUAGE PLPGSQL $$
DECLARE R integer;
BEGIN
  FOR R IN SELECT generate_series(1,10000) LOOP
    perform * from bench where a IN (20,40,60,80,100,120,140,160,180,200);
  END LOOP;
END;
$$

DO LANGUAGE PLPGSQL $$
DECLARE R integer;
BEGIN
 FOR R IN SELECT generate_series(1,10000) LOOP
   perform * from bench where a IN (20,40,60,80,100,120,140,160,180,200) and b between 1000 and 10000;
 END LOOP;
END;
$$

explain select * from bench where a IN (20,40,60,80,100,120,140,160,180,200);
explain select * from bench where a IN (20,40,60,80,100,120,140,160,180,200) and b between 1000 and 10000;
Výsledne čas u mne je 0.210s v případě BETWEEN oproti 0.294s v případě bez between. Takže pohádky vyprávíš hezký, ale je to evidetně jinak a to between databáze nějak využít umí. To dokládá i výpis z těch explain, který dokládaj, že když má databáze k dispozici rozumnou intervalovou podmínku, tak ji použije daleko radši než rozsypanej čaj primárního klíče.

25.5.2012 22:42 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Měřit výkonnost nějakých dotazů na kódu, který dělá něco úplně jiného, je dost zvláštní postup. Měřit výkonnost konkrétních dotazů pro aplikaci na tabulce, která neodpovídá zadání, nad daty, která se zadání nepodobají ani s oběma zavřenýma očima, a s dotazem, který vypadá jinak, než výsledný dotaz v aplikaci, je taky dost zvláštní postup.

Proč se tady pořád oháníte přesným zadáním, a pak řešíte něco jiného nebo občas v zadání něco přehlídnete?

Pokud chcete od uživatele dostat co nejvíc chyb, je textbox opravdu ideální řešení. Pokud mu chcete práci usnadnit, je mnoho lepších řešení.

Jinak u mne na PostgreSQL 9.1 ten SELECT bez between trvá průměrně asi 0,300 ms (nejhorší 0.335 ms, nejlepší 0,298 ms), s between průměrně asi 0,400 ms (nejhorší 0,414 ms, nejlepší 0,374 ms). Vašim způsobem počítáno je ten přidaný BETWEEN o třetinu pomalejší.

Ta první dvě porovnání jsem každé spustil jen třikrát každý test vždy na čerstvě založené databázi (samozřejmě bez těch vnějších smyček, které z toho dělají nesmysl), a k velkému překvapení je varianta s cyklem rychlejší:
DO LANGUAGE PLPGSQL $$
DECLARE R integer := 0;
BEGIN
   INSERT INTO bench(a,b) VALUES 
		(r*20+1 ,r+1),(r*20+2 ,r+2),
		(r*20+3 ,r+3),(r*20+4 ,r+4),
		(r*20+5 ,r+5),(r*20+6 ,r+6),
		(r*20+7 ,r+7),(r*20+8 ,r+8),
		(r*20+9 ,r+9),(r*20+10 ,r+10);
   DELETE FROM bench WHERE a IN (r*20+1,r*20+2,r*20+3,r*20+4,r*20+5,r*20+6,r*20+7,r*20+8,r*20+9,r*20+10) AND b between r+1 and r+19;
END;
$$;


1.478 ms
1.551 ms
1.504 ms

DO LANGUAGE PLPGSQL $$
DECLARE R integer := 0;
 S integer;
BEGIN
   FOR S IN SELECT generate_series(1,10) LOOP
	   INSERT INTO bench(a,b) VALUES (r*20+s, r+s);
   END LOOP;
   FOR S IN SELECT generate_series(1,10) LOOP
	   DELETE FROM bench WHERE a=r*20+s;
   END LOOP;  
END;
$$;

1.428 ms
1.401 ms
1.396 ms
Když už vymýšlíte testy, které s reálnou aplikací mají pramálo společného, zkuste vymyslet takové, které nevyvrací vaše tvrzení. Ale oceňuju, že jste ten druhý test IN versus IN+BETWEEN napsal tak, aby se mnou popsané výhody řešení bez BETWEEN nemohly uplatnit. Byl to dobrý pokus, bohužel to nestačilo.
26.5.2012 01:15 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
A víš proč? Nevím, jestli jsi do databáze vůbec nějaký data nasypal, ale podle časů co ti z toho lezou jsem si na 99% jistej, že jsi nevytvořil statistiky. Protože to mi čas u dotazu BETWEEN, když databáze nemá statistiky, vychází přesně stejně. Že mám pravdu? Kromě toho měřit čas na jedinim dotazu, navíc čistě po vytvoření db je totální blbina, testy se naopak dělaj na databázi, co už je nějakou dobu v běhu, aby se "usadila do paměti" a co nejlépe simuloval dotaz v produkčním prostředí. Z toho co píšeš se mi dokonce zdá, žes to snad dokonce testoval nad prázdnou databází, pokud jo, tak to už vůbec no comment.

Evidentně Ti moje testy vyšli úplně stejně jako mě (proč bys je jinak upravoval?) a tak jsi hledal, co kde ohnout, aby to vyšlo po tvym. A poté, co jsi promazal db, takže se ztratili statistiky, tak Ti vyšel dobře test s between. A poté, co jsi udělal do databáze jen jeden dotaz, kde veškerá režie okolo s natáhnutím db byla víc než rychlost samotnýho dotazu a nesebraný statistiky Ti to zabili úplně, tak jsi bez jediného argumentu vše nepohodlné označil za blbost a prohlásil: hurá, zvítězil jsem. Co dodat.

PS: Jen namátkou: proč z toho ty smyčky dělaj nesmysl? Co to je jiného než postupná editace různejch uživatelů? Nesmysl to je z jedinýho důvodu: protože potom už se rozdílná rychlost těch dotazů projeví a nehodí se Ti to do krámu, že?

PPS: Stejně jako je krásný, jaks tydle smyčky odstranil, ale tu vnitřní tam nechal. Protože kdybys těch dotazů poslal do databáze opravdu deset, jako v Tvym algoritmu, a ne takhle jeden ve smyčce, tak by Ti to zas nevyšlo, protože by se projevila režie, která v takhle zmrvenym testu převažuje.

Churchil měl pravdu.

26.5.2012 09:22 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Dotaz pouze s IN má tu výhodu, že jen načte data z indexu, vůbec nemusí načítat data z tabulky. Tuhle výhodu vy jste eliminoval tím, že jste cyklem donutil databázi načíst data do paměti a hvězdičkou jste ji donutil číst data z tabulky v obou případech. S reálnou aplikací to nemá nic společného, v jejím případě to databáze bude muset přečíst z disku. V produkci ten dotaz taky poběží jen jednou, takže měřit ho tak, že ho spustíte mnohokrát hned za sebou v jednom spojení je nesmysl -- tím ověříte nanejvýš schopnost kešování, ale o reálném provozu vám to neřekne nic.

Vaše testy jsem nezkoušel, ty chyby byly evidentní na první pohled, takže jsem ty největší nesmysly odstranil dřív, než jsem se tím vůbec začal zabývat.

Postupná editace různých uživatelů se bude do databáze posílat v různých spojeních, v různých časových okamžicích, s různými daty. Navíc jedna z věcí, která se tím testovala, je schopnost databáze optimalizovat cykly. A vy to uděláte testem, který vychází z předpokladu, že databáze cykly neoptimalizuje. Myslíte, že výsledky takového testu budou o něčem vypovídat?

Tu vnitřní smyčku jsem tam nechal, protože nejvěrněji napodobuje to, co udělá aplikace -- prepared statement, do které se jen opakovaně sypou data.
26.5.2012 10:51 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
První důvod, proč je to co píšete nesmysle je, že postgresql index only scan umí až od verze 9.2.(a u Mysql by to bylo totéž, protože má clustered index, tj. data uložená v PK, to už jsem Vám taky vysvětloval). Druhým, ještě zřejměší: bavili jsme se o výkonnosti dané podmínky u klausule DELETE. To jako chcete říct, že DELETE nepotřebuje pracovat se samotnými daty? Že pracuje jen s indexem? Blbost, že? Tak jaké donutil? Db by to dělala tak jako tak - ta hvězdička se samozřejmě aplikuje pouze na data vyhovující testu, která by byla mazána. Blábol.

Ne, prepared statement to zdaleka nevystihuje, právě kvůli režii při komunikaci s db. Kterou sice popíráte, ale právě Váš "pseudotest" ji dokázal.

Schopnost databáze optimalizovat cykly? Vau, prosímvás,. víte o databázích vůbec něco? To jako chcete říct, že je vektorizuje? Nebo co s nima jako dělá? PLPGSQL neoptimalizuje ani takové prkotiny, jako r=1; r=3;.

Kdybyste si všimnul, tak v tom cyklu spouštím ty dotazy pokaždé s jinými hodnotami, takže se dostanou na jiné místo indexů atd. Takže co by se mělo cachovat? Cachují se plány, jestli Vám to vadí, tak ty dotazy spustťe pomocí klausule EXECUTE ... USING, která cachování plánů i jakékoli myslitené optimalizaci cyklů zabrání. Ale garantuji Vám, že se výsledek nezmění.

PS: Ano: odstranil jste největší nesmysly: statistiky z databáze (a protože nekřičíte, tak asi i data z databáze). Nu pokud data a statistiky jsou největší nesmysl...
26.5.2012 11:12 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
První důvod, proč je to co píšete nesmysle je, že postgresql index only scan umí až od verze 9.2
Umožnit databázi optimalizaci není nesmysl, nezávisle na tom, zda tu optimalizaci umí už současná verze, nebo ji může umět nějaká budoucí.
To jako chcete říct, že DELETE nepotřebuje pracovat se samotnými daty?
Co by DELETE s daty dělal? Přečte si je, zavzpomíná, co s nimi prožil, a teprve pak je smaže? Zkuste si na disku vytvořit dva soubory,jeden o velikosti 10 bajtů, druhý 10 GB a vyplňte je náhodnými daty. Pak zkuste ty soubory celé přečíst -- u toho velkého to bude trvat podstatně déle. Pak je zkuste oba smazat -- bude to trvat prakticky stejně dlouho.
Ne, prepared statement to zdaleka nevystihuje, právě kvůli režii při komunikaci s db.
Režie komunikace s DB? V jednom případě pošlu dotaz a pak všechna data. Ve druhém případě pošlu dotaz a pak všechna data. Kde je rozdíl?
Takže co by se mělo cachovat?
Kešují se například diskové operace, spousta operací se může odložit a udělat až najednou na závěr -- zápisy dat, indexy, diskové operace...
Ano: odstranil jste největší nesmysly: statistiky z databáze (a protože nekřičíte, tak asi i data z databáze).
Zkuste se zamyslet nad tím, co dělají následující dva příkazy. Mohly by vám být povědomé.
DO LANGUAGE PLPGSQL $$
DECLARE R integer;
BEGIN
FOR R IN SELECT generate_series(1,10000) LOOP
   INSERT INTO bench(a,b) VALUES 
                    (r*20, r*1000);
END LOOP;
END $$;
analyze bench;
Nekřičím, protože nemíním reagovat na vaše ničím nepodložené a neopodstatněné výmysly. Já taky můžu svou argumentaci postavit na tom, že jste si ta čísla určitě vymyslel, ale to pak tahle debata bude už úplně k ničemu.
27.5.2012 03:23 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Bavíme se o výkonu dotazu na konkrétní databázi: a na té konkrétní databázi byla prostě Tvá argumentace že něco znevýhodňuju nepravdivá.

Ano - delete 10GB souboru je chvíle, protže ve filesystému není třeba označovat volné bloky. Tady se ovšem bavíme o 8B záznamu mazaném v databázi, kde JE třeba na tu stránku sahat tak jako tak (označit smazaný záznam). Vzhledem k tomu, že výkon DB je defakto podmíněn množstvím IO, které se u DB nezmění, zatímco u filesystému ano, je příměr nesmyslný.

--

V tom, že se zápisy mohou cachovat máš pravdu - nicméně vzhledem k tomu, že se jedná v obou případech o stejné diskové operace (zapisují se stejná data, upravuje index stejně atd..), tak to nemá vliv. Zápis také probíhá najednou a může být odložený, a narozdíl od čtení se zapisuje do diskové cache, což je mnohem rychlejší (samozřejmě to přestává platit v případě 100% vytížení disku, ale to v tomto případě není). Takže toto cachování se na tom, že jeden dotaz běží třikrát rychlejc než druhej neprojeví.

Navíc i kdyby projevilo, tak jestli někdo dělá více zápisů a tedy více šetřil, tak deset postupných insertů. Takže jestli to cachování mění poměry mezi výkonností dotazů, tak to rozdíl zmenšuje. Takže tímdle to rozhodně neomluvíš.

---

To, proč Ti vyšel čas stejnej, je jednoduchý: režie PLPGSQL kódu zdaleka převýší režii čas dotazu. Prostě si zvolil naprosto nesmyslnej test. Když to napíšeš alespoň jako sql funkci, tak už je rozdíl znatelnej:
create function bnch(r integer) returns void language sql as
$$
   INSERT INTO bench(a,b) VALUES 
		($1*20+1 ,$1+1),($1*20+2 ,$1+2),
		($1*20+3 ,$1+3),($1*20+4 ,$1+4),
		($1*20+5 ,$1+5),($1*20+6 ,$1+6),
		($1*20+7 ,$1+7),($1*20+8 ,$1+8),
		($1*20+9 ,$1+9),($1*20+10 ,$1+10);
   DELETE FROM bench WHERE a IN ($1*20+1,$1*20+2,$1*20+3,$1*20+4,$1*20+5,$1*20+6,$1*20+7,$1*20+8,$1*20+9,$1*20+10) AND b between $1+1 and $1+19;
$$;

create function bnch2(r integer) returns void language sql as
$$
   INSERT INTO bench(a,b) VALUES ($1*20+1, $1+1);
   INSERT INTO bench(a,b) VALUES ($1*20+2, $1+2);
   INSERT INTO bench(a,b) VALUES ($1*20+3, $1+3);
   INSERT INTO bench(a,b) VALUES ($1*20+4, $1+4);
   INSERT INTO bench(a,b) VALUES ($1*20+5, $1+5);
   INSERT INTO bench(a,b) VALUES ($1*20+6, $1+6);
   INSERT INTO bench(a,b) VALUES ($1*20+7, $1+7);
   INSERT INTO bench(a,b) VALUES ($1*20+8, $1+8);
   INSERT INTO bench(a,b) VALUES ($1*20+9, $1+9);
   INSERT INTO bench(a,b) VALUES ($1*20+10, $1+10);
   DELETE FROM bench WHERE a=$1*20+1;
   DELETE FROM bench WHERE a=$1*20+2;
   DELETE FROM bench WHERE a=$1*20+3;
   DELETE FROM bench WHERE a=$1*20+4;
   DELETE FROM bench WHERE a=$1*20+5;
   DELETE FROM bench WHERE a=$1*20+6;
   DELETE FROM bench WHERE a=$1*20+7;
   DELETE FROM bench WHERE a=$1*20+8;
   DELETE FROM bench WHERE a=$1*20+9;
   DELETE FROM bench WHERE a=$1*20+10;
$$;

explain analyze bench(1111);
explain analyze bench(2222);
Samozřejmě čísla si měň jak chceš, vychází to +- furt stejně. Mě to vychází 1.5ms ku 1.9ms. SQL funkce má samozřejmě režii (tadle nejde ani inlinovat), takže výslednej poměr bude značně větší, ale už takhle to dokazuje, že tam rozdíl je.

--

Ohledně dotazů s between a bez: psal jsi že vymažeš databázi, nic víc. Vycházím z toho že píšeš (a když tvrdíš takový s odpuštěním blbiny, tak pak už Tě podezřívám z každý blbosti). I když přistoupím na Tvoji pochybnou metodiku (teda promazávat db odmítám, to je fakt padlý na hlavu, výkon db stojí na tom, že si používaný data v drží v paměti) a měřil jeden dotaz, tak u mne i jeden dotaz s BETWEEN trvá kratší dobu než bez: typická doba pro BETWEEN dotaz je 0.0090ms, bez BETWEEN 0.0100ms. Ověřeno na mnoho dotazech na různé datové stránky.

V jednom máš trochu pravdu: vypadá to, že když dělám náhodné dotazy přes celou databázi, tak je sice BETWEEN rychlejší, ale má o něco větší sklony k občasnýmu zalagování. Pochopitelně, protože používá další index, kterej nemusí bejt v paměti (zkouším na vývojový konfiguraci co ji moc k dispozici nemá). Tendle delší čas se asi projevil u Tvýho testu na čerstvý databázi, kde to bude mít stejnej problém.

Jenže v typickém použití se edituje pouze malá množina aktuálních dat (kdo šahá x let zpátky?) a navíc právě ta data, která db před chviličkou načetla pro editaci. Takže správná metodika je spustit dotaz dvakrát za sebou a brát druhej čas. V tom případě mi to vyjde cca 0.033ms ku 0.055ms a naopak lagovat začne dotaz bez BETWEEN! což je opět pochopitelný, protože při druhym dotazu je ten interval dle kterýho se selektí určitě v paměti, zatímco select přes id jde hrabat do bitmapovýho indexu, kterej musí projít celej a paměťová náročnost je ve výsledku větší.

Jak jsem již psal: to, že při dotazu s BETWEEN volí databáze jinej plán, smysl prostě má, DB to nedělá pro nic za nic ale proto, že tu podmínku s BETWEEN umí s výhodou využít.

27.5.2012 10:15 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Kdyby v souborovém systému nebylo při mazání potřeba označovat volné bloky, za chvíli vám dojde místo na disku -- budou ho zabírat smazané soubory. Volné bloky v souborovém systému se pak samozřejmě označují v metadatech, ne v datovém prostoru. Stejně to dělá i databáze.

Mně nevyšel stejný čas, v obou testech byly vaše optimalizace evidentně pomalejší. Nevidím tam nic, proč by režie PLPGSQL měla být v jednom případě větší, než ve druhém, takže ji můžu jako stejnou konstantu v obou případech odečíst.

Jste si jist, že v tom vašem příkladu použije PLPGSQL prepared statement?
Ohledně dotazů s between a bez: psal jsi že vymažeš databázi, nic víc.
Ne, nepsal. Pořád máte spoustu řečí o tom, jak mám pozorně číst - že byste si je vzal taky k srdci? Nepsal jsem o mazání databáze, ale o práci nad čistě založenou databází -- založenou posloupností 4 příkazů okopírovanou od vás. A nepsal jsem to u SELECTů s BETWEEN, ale u INSERTů a DELETEů. V případě SELECTů se totiž obsah databáze nemění, takže opakované testy lze plus mínus dělat nad stále stejnou databází.

Zkuste si ty dotazy porovnat nad nějakými reálnými daty, třeba pro sto uživatelů. Za období budete mít průměrně třeba 10 záznamů. Takže dotaz podle ID najde v indexu 10 záznamů a ty načte. Dotaz podle BETWEEN najde podle indexu 1000 záznamů, ty načte a bude je sekvenčně procházet a porovnávat s ID. No, ona to ta databáze ve skutečnosti takhle dělat nebude a sestaví plán přesně opačně, tj. načte těch 10 záznamů podle ID a pak jen zkontroluje tu BETWEEN podmínku. Takže je to jen příklad předčasné optimalizace. Navíc když už se do takové optimalizace chcete pouštět, měl byste index explicitně vytvořit jako B-tree. Dnes je to sice default, ale to se může změnit, a hash index vám pro BETWEEN bude houby platný. Když už budete v tom měnění indexu, aby se neprojevil výše popsaný problém, předělejte ho rovnou na složený index, buď user_id + datum nebo datum + id. Pak ta optimalizace začne dávat smysl. A taky začne být jasné, že má smysl se s ní zabývat až tehdy, když to bude úzké místo aplikace.
27.5.2012 13:23 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Hele, proč tvrdíš takový blbiny, když stačí např. jeden pohled do manuálu k databázi k ověření: http://www.postgresql.org/docs/8.0/static/storage-page-layout.html Samozřejmě, že se mazání dat označuje nejen do metadat, ale i do samotnejch stránek - konkrétně při mazání musíš vyplnit TXID mazající transakce. Dyk už to je směšný: do krve mě tady o něčem přesvědčuješ, ale cokoli řekneš o architektuře db, tak je blbě. V MYSQL jsou data uložený přímo B+stromě clustrovanýho indexu, takže opět při mazání se mění přímo datová stránka na které je záznam uložen.

Ohledně testu na více dotazů: co přesně jste zvoral nevím, v čerstvé databázi se může pokazit cokoli. Např. třeba může vadit právě ta podmínka between, protože ještě není v paměti index. Když se to nedělá na čerstvé databázi, čili v reálných podmínkách, čas vyjde stejnej, když se to nevolá z PLPGSQL kódu, kde je větší režije, tak je čas lepší pro víc dotazů, kdybys to volal jako n příkazů, tak ještě navíc plus režie přenosu. Už jste si zkusil ty SQL funkce?

Založení databáze je založení databáze. Příkaz CREATE. Pokud nad ní děláte ještě něco dalšího (vkládáte data, analyzujete), už to není čerstvě založená databáze. Nicméně přestaňme se hádat nad slovíčky: uznávám, že jsem Vás podezíral z větší blbosti než jste ve skutečnosti udělal, nicméně furt si stojím za to, že to, jak jste nastavil testcase je blbost furt. Jen ne tak velká :-)

Zkus ty data porovnat nad nějakými reálnými daty... to myslíš vážně? To fakt nejsi schopnej alespoň základní abstrakce? Samozřejmě, že když budu hledat data danýho uživatele s rozmezím daných dnů, tak založím index (userid, den), mění to něco? A pokud sloupec B vyjadřuje nějak zakódované userid + den, co je na těch datech nereálného? Tak si to zkus, dokonce todle vyjde i na čerstvý tabulce, odkomentuj a zakomentuj to between:
drop table bench ;drop table bench ;
CREATE TABLE bench
(
a integer primary key,
b integer, /*userid*/
c integer, /*den*/
constraint uniq unique(b,c)
);

insert into bench(a,b,c) select (r % 2) * 100000 + (r/2), r / 100,  r % 100 from generate_series(1,100000) u(r);
analyze bench;

explain analyze select count(a) from test.bench Where a in (4475,104475,4476,104476,4477,104477,4478,104478,4479,104479)  
/*AND b=89 AND c  BETWEEN 50 AND 50+10*/
;


explain analyze select count(a) from test.bench Where a in (3215,103215,3216,103216,3217,103217,3218,103218,3219,103219)   
/*AND b=64 AND c  BETWEEN 30 AND 30+10*/
To je úplně m modelovej případ - edituju nějakej subset dní z uživatele, idčka jsou trochu rozházený. A to je těch záznamů jen deset, s vzrůstajícím počtem je intervalovej dotaz efektivnější.

Píšeš předčasná optimalizace: Takže už začínáš uznávat, že to je lepší řešení? Nebo je to jen odvádění od tématu? O tom, zdali a jak moc se to vyplatí jsem nepsal, jen jsem tvrdil, že je to rychlejší, což jsi popíral. Opět se snažíš vykroutit tím, že polemizuješ s něčím jiným, než co tvrdím.

Nicméně pokud tedy tvrdíš, že to je předčasná optimalizace, tak je evidentně výkonu dost, čili vyhovuje nejrychleji napsané řešení. Vzhledem k tomu, že jsi už tuším uznal, že mé řešení je kratší, takže to znamená, že je pro první nástřel lepší.
27.5.2012 13:40 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Pokud po každý nový typ pohledu musíte zakládat nový index pro mazání, není to zrovna dobře spravovatelná aplikace. A dělat to jenom proto, aby se nějaký dotaz prodloužil (nebo klidně i zkrátil) o pár milisekund...

Předčasná optimalizace vůbec nemusí být lepším řešením. Naopak jedním z důvodů, proč se předčasné optimalizace nedoporučují, je to, že velice často situaci naopak zhorší. Nejrychleji napsané řešení a kratší řešení na počet znaků příkazu jsou dvě různé věci, které spolu vůbec nesouvisí.
27.5.2012 14:59 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie

Teda ty už fakt nevíš, jak se z toho vymluvit. Vzhledem k tomu, že tazatel chce editovat všechny data datného uživatele (buď s omezením na dané rozmezí dat nebo ne, podle toho bude vypadat i ten dotaz a potřebný index), tak tam takovýto index bude tak jako tak. Takže opět nesmyslný argument.

1) Proč by dobře napsaná optimalizace něco zhoršovala? Jak jsem dokázal, mnou navržené optimalizace fungují. Pokud píšeš optimalizace, co nefungují.... :-)
2) Já jsem nikdy netvrdil, že ty optimalizace musím použít. Pouze, že je ta možnost. Spor byl o to, zdali ty optimalizace, pokud je použiju, fungují.
3) Dodání podmínky na datum to podstatně zhoršit nemůže, protože databáze má furt možnost si vybrat plán dle IDček. To je totiž typický přístup: "nech to na db" - dám db maximum informací a nechám ji rozhodnout.
4) Kratší kód není nutně jednodušší, ale pokud jsou obě řešení kulturně napsaná (tzn. nešetří se na čitelnosti), tak je tam velmi silná korelace. A pokud jsou oba kódy myšlenkově primitivní (tzn. člověk při psaní neztrácí čas myšlením a rovnou píše), pak to platí, což je přesně tento případ. Evidentně to tak připadá i tazateli (proč by to tak jinak chtěl dělat, když se bojí dopadu na výkon)?
5) Tazatel se neptal, co je nejrychleji napsané, ale co je výkonnostně dobré řešení. A jestli si přečteš, má odpověď zní: neřeš to a napiš to nejednodušejc, což je IMHO smazat vše a znovu založit. Navíc, kdyby Tě výkon trápil, je tento přístup podle mě efektivní a navíc se dá snadno ještě dále optimalizovat. Ty jsi začal prosazovat, že to musí zapsat pomocí updatů, protože to bude pro databázi lepší (, či protože nejde v mém přístupu zajistit verzování. Obé jsem vyvrátil.) Takže jestli někdo prosazovat předčasné optimalizace, já to nebyl.
27.5.2012 15:27 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Kdyby si tazatel myslel, že nejjednodušší je smazat a znovu zapsat, nepsal by, že podle něj je nejjednodušší je updatovat, ale napadla ho (předčasná) optimalizace, že se dá vše smazat a znovu zapsat. A neptal by se, zda ta optimalizace opravdu dává smysl. Nějaký peprný komentář o schopnosti přečíst zadání a řídit se jím si doplňte sám, jde vám to moc dobře.
27.5.2012 17:02 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
ale bolo by to podla mna narocnejsie kazdy jeden zaznam skontrolovat a nasledne updatovat alebo neupdatovat, ako ich jednoducho vsetky naraz zmazat
Jednoducho pro Tvojí informaci znamená jednoduše. Tazatel evidentně považuje řešení za jednodušší, akorát má obavy o výkon tohoto jednoduchého řešení:
avsak obavam sa, ci to moc nezatazi databazovy server...
Takže je to přesně naopak než píšeš. Akorát si myslí, že složitější řešení (update po jednom) výkonnosti nepomůže.
27.5.2012 17:13 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Jestli si myslíte, že skočím na tuhle vaši manipulaci, kdy záměrně z dotazu něco vynecháte, tak se mýlíte. Jako prozrazení toho, že vám ve skutečnosti vůbec nejde dobrat se správného řešení, ale za každou cenu "zvítězit", to myslím stačí.
27.5.2012 17:48 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Jakou manipulaci? Vy chcete popřít, že když tazatel obě řešení srovnává a jedno z nich označil jako jednoduché, tak že tím myslí, že je jednodušší než to druhé? Co tím tedy myslel? Vysvětlete tedy význam toho slova jednoduše v té větě. Co tím slovem tazatel myslel? Že je to složitější řešení???

PS: Ano: tazatel označil i algoritmus updatu za "jednoduše". Jenže si musíte přečíst celou větu: Někdo by mohl namítat, proč ty uživatele jednoduše neupdatuju, ale to.... Tzn. tazatel říká:
Nějakej Filip Jirsák by mohl namítat, že to mám jednoduše po jednom updatovat. Jenže tam bych ještě musel kontrolovat co vlastně updatovat a ve výsledku by to bylo náročnější, než JEDNODUCHÉ smazání a znovuvložení všeho.
Tazatel tedy s tím prvním jednoduše právě polemizuje, nikoli, že to tvrdí. Tzn. že na první pohled jednoduché řešení je vlastně je podle něj složitější i pomalejší. Takže fakt nevím, co jsem úmyslně vynechal. Já jsem Vás pouze odkázal na kus textu, z kterého jednoznačně plyne, že autor DELETE/INSERT algoritmus považuje za nejjednodušší a nijak jsem to extra neřešil, protože jsem opravdu nečekal, že neumíte uznat chybu ani v takhle jasné záležitosti.
Heron avatar 22.5.2012 13:34 Heron | skóre: 50 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: MYSQL zmazanie velkeho mnozstva zaznamov pre usera a zaroven ich vlozenie
Asi již vše ohledně rychlosti bylo řečeno, ale v celé diskusi mi chybí jedna věc, kterou jsou transakce. Ať to již budeš dělat pomocí jednotlivých select, insert, delete, nebo jinak, určitě je nezbytně nutné tu skupinu příkazů uzavřít do jedný transakce. Obzvláště v multiuser prostředí.

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.