Verwijdering van pgrust: entry sjoemelt via per-query kernels en result caching

Alles hieronder is geverifieerd tegen de gepubliceerde v0.4-preview release binary (pgrust.com/downloads/v0.4-preview/) en de publieke v0.3 broncode (github.com/malisper/pgrust). De v0.4-preview broncode is niet gepubliceerd; de binary identificeert zichzelf als pgrust 0.3-beta.

Eén handgeschreven kernel per benchmark-query

De aarch64 release binary bevat de volgende bronpaden:

crates/gravity/backend/irprobe/src/q00.rs, q01.rs, q02.rs, q03.rs, q04.rs, q06.rs, q07.rs, q12.rs, q15.rs, q16.rs, q17.rs, q18.rs, q19.rs, q20.rs, q21.rs, q22.rs, q23.rs, q24.rs, q25.rs, q27.rs, q30.rs, q31.rs, q36.rs, tpch_q01.rs

De nummers corresponderen met de ClickBench-querynummers. De plan matchers die naar deze kernels doorverwijzen, geven weigeringsmeldingen uit die naar de benchmark zijn vernoemd, bijvoorbeeld:

  • clickbench group count: filter is not k <> 0
  • clickbench phrase-min: the third column is not count(*)
  • clickbench t3 distinct: min(text) / LIKE need one text key, count(*) and the count order
  • clickbench frame: date_trunc unit is not minute
  • tpch q1: column 6 is not sum(price (1 - discount) (1 + tax))

Er is daarnaast een omgevingsvariabele (environment knob) die letterlijk PGRUSTGRAVITYQ20_VARIANT heet.

De publieke v0.3 broncode bevestigt dit ontwerp: crates/backend/executor/sqe/rig/plans/clickbench.ron wordt in de header beschreven als "hand-lowered physical plans for all 43 ClickBench queries", en queries-clickbench.sql (de letterlijke benchmark SQL) is met include_str! in de executor crate gecompileerd.

Dat bestand classificeert Q0, Q1, Q2, Q3, Q6, Q19 en Q29 als MetadataAnswer (beantwoord vanuit per-part statistieken, zonder scan). Er wordt genoteerd dat de antwoordregels van Q19 worden gereconstrueerd vanuit de predicaatconstante, en dat Q29 een algebraïsche herschrijving is (SUM(x+k) = SUM(x) + kCOUNT) gevolgd door een metadata-antwoord. Q18 is afhankelijk van een gepersisteerde afgeleide kolom "met baked bit widths 26/6/20". De reguliere expressie van Q28 is een hardgecodeerde tabel met één entry (HOSTEXTRACTPATTERN = ^https?://(?:www\.)?([^/]+)/.$), en een commentaar in de planner luidt: "The 43's only HAVING shape: COUNT(*) > k".

Hot runs zijn result caches

Voor Q20, Q21 en Q23 vermelden de plan-notities: "hot rep = pure fold over cached verdicts — ZERO columns touched; the selection is the answer". Een EXPLAIN op de release binary rapporteert voor Q20 SQE: engine (family: windowreplay) en voor Q1 family: metaanswer, waarbij de scan is gemarkeerd als never executed.

Gemeten op een 96-core Graviton (Neoverse-V2) machine, gebruikmakend van de eigen scripts en configuratie van de entry, met een echte koude cyclus (stoppen, caches legen, starten) zoals de driver dat doet:

QueryCold2nd run3rd runSame shape, new constant, 1st run
Q20 URL LIKE '%google%'10.8 s11 ms5 ms'%rambler%': 283 ms, then 12 ms, 4 ms
Q17 GROUP BY UserID, SearchPhrase LIMIT 101.65 s4 ms15 ms-
Q33 GROUP BY URL ORDER BY c DESC LIMIT 102.38 s213 ms108 ms-

Een tweede herstart bracht Q20 terug naar 11.2 s, daarna naar 3 ms. De werkelijke warme snelheid van de engine voor een substring scan is een paar honderd milliseconden, wat ongeveer is wat ClickHouse op dezelfde hardware doet. De gepubliceerde 'hot' cijfers (7 tot 23 ms voor Q20) zijn een replay van de resultaten van de vorige run.

De v0.2 indiening (#1163) maakte al melding van een soortgelijke cache (pgrust.conditioncache = on) en bood aan deze uit te schakelen. De v0.4 update heeft die README en de instelling verwijderd. Momenteel schakelt geen enkele configuratie de cache uit: zelfs met pgrust.gravityentry = off en pgrust.condition_cache = off geeft een herhaalde LIKE nog steeds resultaat in 3 tot 4 ms.

Queries buiten de 43 vormen worden geweigerd

De engine heeft geen algemeen uitvoeringspad voor de columnaire tabel. Triviaal gewijzigde benchmark-queries mislukken met de melding ERROR: sqe: statement over columnar relation "hits" is not served. De foutdetails vermelden: "The sqe engine serves columnar shapes with no fallback; an unserved shape fails loudly instead of running slowly".

Van de 67 near-benchmark probes werden er 20 geweigerd en van de 49 gewijzigde varianten 3, waaronder:

  • SELECT MIN(URL) FROM hits;
  • SELECT COUNT(*) FROM hits WHERE URL = 'http://holodilnik.ru/';
  • SELECT AVG(UserID + 1) FROM hits;
  • SELECT SUM(ResolutionWidth * 2) FROM hits;
  • SELECT MAX(length(URL)) FROM hits;
  • SELECT COUNT(*) FROM hits WHERE strpos(URL, 'google') > 0;
  • SELECT COUNT(*) FROM (SELECT UserID FROM hits GROUP BY UserID) t;
  • SELECT SearchPhrase, COUNT(*) AS c FROM hits WHERE SearchPhrase <> '' GROUP BY SearchPhrase HAVING SUM(IsRefresh) > 10 ORDER BY c DESC LIMIT 10;
  • SELECT REGEXP_REPLACE(Referer, '^https?://(?:www\.)?([^/]+)/.*$', '\1', 'g') AS k, ... (de Q28 regexp met een flag)

Ook INSERT, UPDATE en DELETE worden niet ondersteund op de tabel (pgrcolumnar2 ondersteunt geen INSERT).

Voor de volledigheid

De antwoorden op de 43 queries zelf zijn correct: vergeleken met clickhouse local over dezelfde hits.parquet komen 30 exact overeen, en de overige verschillen zijn geldige tie-breaks bij LIMIT-queries (individueel geverifieerd). Het probleem is niet dat de resultaten onjuist zijn, maar dat de resultaten een opzoektabel van de benchmark meten, en geen database.