Portál AbcLinuxu, 13. května 2025 00:54
SELECT COUNT(id) FROM data id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE data index NULL jiny_boolean_key 1 NULL 74695 Using index
SELECT COUNT(*) FROM data id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE data index NULL jiny_boolean_key 1 NULL 72276 Using indexje to normální vlastnost ?
select sum(if(nova,1,0)), /*nová*/ sum(1), /*vše*/ sum(if(stav=2),1,0) /*přečtená*/ from dataTakto by se mezi operacemi s tabulkou odlehčilo s počítáním. Je fakt, že po změně tabulky chce člověk většinou(uživatel vždy) vědět stav, takže by se stejně countovalo. V každém případě by toto asi ulehčilo tak jak tak. Ale zas takový dotaz proleze tabulku celou, i když jen jednou.
select sum(nova,1,0), /*nová*/ sum(1), /*vše*/ sum(stav=2) /*přečtená*/ from data
SELECT /*!40001 SQL_NO_CACHE */ * FROM `data`;Je to zápis tohoto dotazu nebo mi unikl nějaký divný dotaz tohoto zápisu?
Time Action Message Duration / Fetch 3 1 08:49:32 select count(*) from data LIMIT 0, 1000 1 row(s) returned 0.062 sec / 0.000 sec 3 2 08:49:48 select count(id) from data LIMIT 0, 1000 1 row(s) returned 0.047 sec / 0.000 sec 3 3 08:50:07 select count(1) from data LIMIT 0, 1000 1 row(s) returned 0.047 sec / 0.000 sec 3 4 08:50:34 select count(*) from data_pozn LIMIT 0, 1000 1 row(s) returned 0.421 sec / 0.000 secdata 7293 data_pozn 386047 Kámoš mi to testoval teď přes EMS(s i bez limitu) a opět kolem 1,4s. EMS se zdá kapánek brzda. Tzn. že mám věřit profilování v phpmyadmin, kde po součtu vychází cca stejné časy jak u workbench ?
count(*)
nad pár záznamy, prostě nemůže trvat sekundu, když si pustím tento dotaz jako první nad nepoužívanou DB:
mysql> SELECT count(*) FROM generator_1m; +----------+ | count(*) | +----------+ | 1048576 | +----------+ 1 row in set (0.01 sec)
SET profiling = 1;a pak při zobrazení:
SHOW PROFILES;či
SHOW PROFILE;A pokud by nešlo věřit tomu, tak už není čemu…
Všimněte si, že v obou případech se jede přes jeden a ten samý index. Tento index je nad typem boolean (null nejspíše není povoleno) a lze se oprávněně domnívat že boolean index bude menší než libovolný jiný index (například nad integer sloupcem). Proto správně optimizer vyhodnotil že pro count(<něco co není null>) bude nejlevnější právě tento index. Zkuste si dohledat velikosti indexů a uvidíte.
@Kit: cena funkce count (stejně jako ostatních agregačních funkcí) závisí na velikosti zdrojové množiny a také na tom kolik máte cílových agregačních skupin daných frází GROUP BY. V tomto případě je počet skupin pouze jedna a cena je v zásadě rovna ceně operace "full index scan" indexu nad non null sloupci.
Je nesmysl aby uvedený dotaz nad 7500 řádky trval 1,5 s. Buď máte extrémně zatížený stroj (ve smyslu IO operací), nebo extrémně pomalý disk (starý 20+ let), nebo jinou fatální chybu v konfiguraci ( virtualizace, konfigurace paměti, ...). Podělte velikost zjištěného boolean indexu rychlostí cca 10MB/s ( pomalejší disk asi nemáte ) a dostanete přibližný response time na který by jste se měl dostat. V popisovaném případě lze čekat odpověď do 10ms (=načtení cca 75kB dat). V případě zásahu do cache (=opakované dotazy) by pak měl být response time do 2ms (=zpoždění sítě).
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.