Josef Průša oznámil zveřejnění kompletních CAD souborů rámů tiskáren Prusa CORE One a CORE One L. Nejsou vydány pod obecnou veřejnou licenci GNU ani Creative Commons ale pod novou licencí OCL neboli Open Community License. Ta nepovoluje prodávat kompletní tiskárny či remixy založené na těchto zdrojích.
Nový CEO Mozilla Corporation Anthony Enzor-DeMeo tento týden prohlásil, že by se Firefox měl vyvinout v moderní AI prohlížeč. Po bouřlivých diskusích na redditu ujistil, že v nastavení Firefoxu bude existovat volba pro zakázání všech AI funkcí.
V pořadí šestou knihou autora Martina Malého, která vychází v Edici CZ.NIC, správce české národní domény, je titul Kity, bity, neurony. Kniha s podtitulem Moderní technologie pro hobby elektroniku přináší ucelený pohled na svět současných technologií a jejich praktické využití v domácích elektronických projektech. Tento knižní průvodce je ideální pro každého, kdo se chce podívat na současné trendy v oblasti hobby elektroniky, od
… více »Linux Foundation zveřejnila Výroční zprávu za rok 2025 (pdf). Příjmy Linux Foundation byly 311 miliónů dolarů. Výdaje 285 miliónů dolarů. Na podporu linuxového jádra (Linux Kernel Project) šlo 8,4 miliónu dolarů. Linux Foundation podporuje téměř 1 500 open source projektů.
Jean-Baptiste Mardelle se v příspěvku na blogu rozepsal o novinkám v nejnovější verzi 25.12.0 editoru videa Kdenlive (Wikipedie). Ke stažení také na Flathubu.
OpenZFS (Wikipedie), tj. implementace souborového systému ZFS pro Linux a FreeBSD, byl vydán ve verzi 2.4.0.
Kriminalisté z NCTEKK společně s českými i zahraničními kolegy objasnili mimořádně rozsáhlou trestnou činnost z oblasti kybernetické kriminality. V rámci operací OCTOPUS a CONNECT ukončili činnost čtyř call center na Ukrajině. V prvním případě se jednalo o podvodné investice, v případě druhém o podvodné telefonáty, při kterých se zločinci vydávali za policisty a pod legendou napadeného bankovního účtu okrádali své oběti o vysoké finanční částky.
Na lepší pokrytí mobilním signálem a dostupnější mobilní internet se mohou těšit cestující v Pendolinech, railjetech a InterPanterech Českých drah. Konsorcium firem ČD - Telematika a.s. a Kontron Transportation s.r.o. dokončilo instalaci 5G opakovačů mobilního signálu do jednotek Pendolino a InterPanter. Tento krok navazuje na zavedení této technologie v jednotkách Railjet z letošního jara.
Rozšíření webového prohlížeče Urban VPN Proxy a další rozšíření od stejného vydavatele (např. 1ClickVPN Proxy, Urban Browser Guard či Urban Ad Blocker) od července 2025 skrytě zachytávají a odesílají celé konverzace uživatelů s AI nástroji (včetně ChatGPT, Claude, Gemini, Copilot aj.), a to nezávisle na tom, zda je VPN aktivní. Sběr probíhá bez možnosti jej uživatelsky vypnout a zahrnuje plný obsah dotazů a odpovědí, metadata relací i
… více »QStudio, tj. nástroj pro práci s SQL podporující více než 30 databází (MySQL, PostgreSQL, DuckDB, QuestDB, kdb+, …), se stal s vydáním verze 5.0 open source. Zdrojové kódy jsou k dispozici na GitHubu pod licencí Apache 2.0.
Řešení dotazu:
Trošku teorie:
Většinou je lepší použít méně selektů než více. Pokud například pracuješ s velkými objemy dat a použiješ z nej jen pár záznamů, potom je ale lepší použít více selektů.
V tvém případě procházíš stejně všechny data a všechny je budeš zpracovávat, proto použij jeden selekt a pouze projekce (vybre jen ty sloupce, které potřebuješ).
Dále použij mysql_* pro procházení dat:
$res = mysql_query('select ...')
while(($row = mysql_fetch_array($res))
{
}
Tady je hezký příklad: http://www.php.net/manual/en/function.mysql-fetch-array.php
SELECT. Už proto, že kdyby během zpracování každého z těch 3000 mohlo docházet k modifikacím seznamu uživatelů, mohl by v datech vzniknout zmatek. Také by se mohlo případně stát, že by se to "niečo" provedlo jen pro některé uživatele a pro jiné ne.
Uvědom si, že každý SELECT se kompiluje do pseudokódu a teprve ten se provádí. Pokud se dá příkaz napsat jako jeden SELECT, je to k databázi mnohem šetrnější a výkonnější. Navíc celá akce proběhne atomicky.
Systémové prostředky by to zahltit nemělo, protože PHP si data z databáze odebírá postupně jak potřebuje. Obvykle bývá nastaven limit paměti pro proměnné v PHP na 32 MB, ale dá se zpracovat i select se stovkami MB.
Spíš bych se ale zamyslel nad tím: Co vlastně s těmi daty potom děláš? Neukládáš je po modifikaci opět do databáze? To bych v cyklu rozhodně nedělal, ale nechal bych to udělat přímo tu databázi.
dotaz na nějakejch 15kB a výsledek ne o moc víc... + len krátke textové veci, mená, emaily, čísla, dátumyMůže ve výsledku znamenat i více než 0.3 MiB.
Budu ho normálně zpracovávat řádku po řádceJestli myslíš fetch_xxx, tak to na věci nic nemění, že data jsou v result setu načtena všechna.
mysql_unbuffered_query() nedělá to, že by neukládala výsledek na straně klienta, ona ho jen nepřipravuje pro použití v PHP (nedělá z něj typy PHP) a umožňuje zpracování, hned jakmile už nějaká data dojdou. To znamená, že můžete získat rychlost, díky paralelnímu zpracování a ušetřit nějakou paměť díky „nepřekládání dat“, pokud budete dostatečně rychle zpracovávat (což ale v PHP asi těžko půjde předběhnout takový typ dotazu.), ale ty data na straně klienta uložena jsou, jen je hned odebíráte a nejsou tak velká (zvláště pokud je tam spousta smallint, tinyint apod.).mysqli_result::free(), mysqli_stmt::free_result() nebo i třeba imagedestroy() uvolňují prostě paměť ihned, řekněme mimo vyhledávací loop GC.
//pripojení k db
echo memory_get_usage(),"\n";
//$q=mysql_query("SELECT * FROM invoices");
$q=mysql_unbuffered_query("SELECT * FROM invoices"); \\ LIMIT 4000");
sleep(2);
echo memory_get_usage(),"\n";
$s=0;
while($r=mysql_fetch_row($q))
{
$s=$s+$r[0];
//echo memory_get_usage(),", ";
}
echo memory_get_usage(),"\n";
echo memory_get_peak_usage(),"\n";
exit();
Výsledky s normálním dotazem:
685984 4825840 4825840 44789896 44796976s buffered s limitem 4000
686000 1688464 1688464 11289208 11296256výsledky s unbuffered query
685800 695904 695904 696632 716056unbuffered s limitem 4000
686008 689696 689696 690256 715968unbuffered s limitem 20
685816 695920 695920 696648 715216Myslím, že tato data Tvoje tvrzení prostě vyvrací: spotřeba paměti je při unbuffered query defakto identická při 20 i 18000 záznamech. Navíc, kdyby to bylo tak, jak tvrdíš, tak by se data během sleepu načetly a spotřebovali paměť, tam ale k žádnému nárůstu paměti nedochází, k tomu dochází až u buffered query během cyklu. Proto je evidentní, že ani buffered query netahá všechna data hned, pouze je na straně klienta cachuje v okamžiku, kdy jsou poprve přečtena, aby umožnil pohyb zpět po resultsetu (samozřejmě tahá data po "paketech", proto je spotřeba paměti během cyklu vždy pár kroku stejná a pak skočí).
memory_get_usage() a nebo se použije v PHP něco jako:
$pid = getmypid();
exec("ps -eorss,pid | grep $pid", $output);
echo IntVal(trim($output[0])) * 1024,"\n";
Takže je blbost co jsem psal v 1. odstavci a o čem jsem byl přesvědčen (nevím proč) a musel jsem se podívat i do zdrojáků PHP-ka a to i do starších verzí (4.x), ale nenašel jsem nic co by odpovídalo tomu co jsem psal, PHP funkce mysql_unbuffered_query() prostě a jednoduše odpovídá C API mysql_use_result().
).Conected and selected DB Exec ps: 6680576 Start mysql_query() Selected Exec ps: 41750528 Selected after sleep(2) Exec ps: 41750528 Fetched all rows, php sum(id): 16200090000 Exec ps: 41750528 After mysql_free_result Exec ps: 6680576 After mysql_close Exec ps: 6680576U
mysql_buffered_query() to nabýšení na 40MiB nebylo.No generovat tabulku v databázi bych fakt nedooporučoval. Logika v databázi, to ano, ale view? To se bude tak obtížně spravovat, že fuj.Zrovna jsem to otestoval v SQLite na 300 000 záznamech. Vygenerování celé tabulky jedním selectem do jednoho řetězce bylo asi 3x rychlejší, než klasické procházení výsledků selectu cyklem. Možná se to obtížněji spravuje, ale databáze udělá view rychleji než PHP.
foreach($dbh->query("SELECT value as val FROM pokus;") as $row) {
echo 'trtd'.$row['val'].'/td/tr'."\n";
}
Skládání řádek v SQL (12 sekund):
foreach($dbh->query("SELECT 'trtd'||value||'/td/tr\n' as val FROM pokus;") as $row) {
echo $row['val'];
}
Použití pole (9 sekund):
$out=array();
foreach($dbh->query("SELECT value as val FROM pokus;") as $row) {
$out[]='trtd'.$row['val'].'/td/tr';
}
echo implode("\n",$out);
Použití řetězce (9 sekund):
$out='';
foreach($dbh->query("SELECT value as val FROM pokus;") as $row) {
$out.='trtd'.$row['val'].'/td/tr'."\n";
}
echo $out;
Skládání řádek, kombinace s polem (9 sekund):
$out=array();
foreach($dbh->query("SELECT 'trtd'||value||'/td/tr' as val FROM pokus;") as $row) {
$out[]=$row['val'];
}
echo implode("\n",$out);
Agregace v SQL (5 sekund):
foreach($dbh->query("SELECT group_concat('trtd'||value||'/td/tr','\n') as val FROM pokus;") as $row) {
echo $row['val']."\n";
}
Agregace v SQL bez výstupu echo (2 sekundy):
foreach($dbh->query("SELECT group_concat('trtd'||value||'/td/tr','\n') as val FROM pokus;") as $row) {
$line=$row['val']."\n";
}
To poslední měření jsem uvedl proto, aby bylo vidět, jak je echo líné.
Znaky tr a td znamenají <tr> a <td>, ale nechtělo se mi to nahrazovat entitami v celém příspěvku. Kdo chce, domyslí si.
Skládání s polem máš naprosto zbytečně v cyklu, do implode můžeš hodit už ten query.Asi mi něco uniká. Myslíš něco takového?
$result=$dbh->query("SELECT 'trtd'||value||'/td/tr' as val FROM pokus;",PDO::FETCH_COLUMN));
echo implode("\n",$result->fetchAll());
Zkusím to odladit, až budu na původním počítači. V této podobě by to mohlo být i rychlé.
Ohledně údržby kódu: Někteří vývojáři tvrdí, že SQL umí všechno. Dá i nedá se s tím souhlasit, někdy je to za cenu velkých obstrukcí. Souhlasím, že je dobré dělat aplikace jako vícevrstvé, kód se tím často zpřehlední.
V uvedeném případě mi však připadá přidání jedné funkce do SQL a ubrání z PHP jako jednoduchá úprava. Vychází mi však efektivnější. Můžu ještě zkusit porovnat i paměťové nároky jednotlivých řešení.
implode($dbh->query("SELECT 'trtd'||value||'/td/tr' as val FROM pokus;",PDO::FETCH_COLUMN, "\n")
ale to se omlouvám, zas jsem zapoměl na "debilitu" phpka, kde sice něco se tváří jako pole/iterátor, ale to ještě neznamená, že se to dá jako pole nebo iterátor používat, takže todle máš pravdu, to nejde.
Zkusit to s FetchAll je zajímavý, jestli je to fetchAll tedy napsané v něčem rozumějším než PHP, jinak to bude stejné.
V tý udržovatelnosti IMHO nejde až tak o to, že se to udělá jednou, ale o to, že např. za tejden přijde šéf, že chce, aby si mohl člověk tu tabulky "skinovat". V tu chvíli začne db řešení dělat problémy, protože tam se takový věci implantujou daleko hůř.
$result=$dbh->query("SELECT 'trtd'||value||'/td/tr' as val FROM pokus;",PDO::FETCH_COLUMN,0);
echo implode("\n",$result->fetchAll());
Je to asi nejrychlejší řešení z těch, které dělají výstupní agregaci mimo SQL. Zároveň nevypadá příliš složitě, mělo by být obecně použitelné.
Předpokládám, že metoda fetchAll() je napsána v C nebo něčem podobném. Raději použiji takovou funkci než abych iteroval ve skriptu. Beru to od tebe jako dobrý nápad na rozumný kompromis. A že to má 2 řádky místo zamýšlené jedné? To mě vůbec netrápí.
Zpracování skriptu v polovičním čase pro mne znamená zpracování dvojnásobného počtu požadavků klientů nebo pronajaté jedno procesorové jádro místo dvou. V případě některých aplikací to může být docela důležité. Jak už bylo řečeno, cokoliv je rychlejší než PHP. Tím cokoliv můžou být nejen databáze, ale i vestavěné funkce PHP, které obvykle v PHP napsány nejsou.
I když samozřejmě v rozumný databázi jde nadefinovat UDF funkce
Jinak já v podstatě souhlasím. PHP je pomalá mrcha a samozřejmě užívat vestvavěné fce je veskrze doporučeníhodné. Jen ale, že to má i druhou stránku a že je poměrně tenká hranice mezi neoptimalizovaným a přeoptimalizovaným kódem...
Tiskni
Sdílej: