PostgreSQL sau MySQL: stocarea schimbă câștigătorul benchmarkului

|Autor: Echipa editorială QUASA|6 min de citit
PostgreSQL sau MySQL: stocarea schimbă câștigătorul benchmarkului

Între PostgreSQL și MySQL nu există un câștigător valabil pentru orice aplicație: contează interogările dominante și stocarea pe care rulează baza de date. O sinteză a sarcinilor indică un posibil avantaj MySQL la citiri după cheia primară și inserări susținute, respectiv avantaje arhitecturale PostgreSQL la join-uri complexe și căutări JSONB. Acestea sunt orientări pe tipuri de sarcini, nu rezultatele unui singur test comun.

Stocarea poate schimba chiar ordinea unui benchmark. Într-un experiment OLTP separat, făcut cu PostgreSQL și MariaDB, motorul aflat în față s-a schimbat odată cu lățimea de bandă disponibilă. MariaDB este un produs distinct de MySQL, astfel că rezultatul arată cât de mult contează condițiile de I/O, fără să stabilească un câștigător numeric pentru comparația PostgreSQL–MySQL.

Matricea de alegere, după sarcina aplicației

Un scor general amestecă operații cu costuri diferite. Matricea de mai jos arată ce merită să cântărească mai mult în alegere; fiecare rând descrie o posibilă potrivire, nu garantează că un motor va fi mai rapid pe orice set de date.

  • Citire după cheia primară: MySQL cu InnoDB este un candidat puternic când aplicația cere în principal câte un rând după identificator. Contează și ce coloane trebuie returnate.
  • Scrieri: inserările, actualizările și ștergerile au costuri diferite. Un debit bun la inserări nu spune singur cum se va comporta un amestec de operații susținute.
  • Join-uri: PostgreSQL merită luat în calcul pentru interogări cu mai multe tabele, filtre și agregări; distribuția datelor și planul ales rămân decisive.
  • JSON: PostgreSQL oferă indexare GIN pe JSONB pentru căutări variate. MySQL poate indexa valori extrase din căi JSON cunoscute și elemente din tablouri JSON.
  • Analiză: rapoartele care parcurg și agregă multe rânduri cer o evaluare separată de tranzacțiile scurte. O citire rapidă după identificator nu prezice timpul unui raport complex.

Cheia primară și scrierile solicită stocarea diferit

Căutarea după cheia primară ajunge la rând prin indexul InnoDB sau prin indexul și heap-ul PostgreSQL.

În InnoDB, datele rândului sunt organizate în indexul grupat al cheii primare. O căutare după acea cheie poate găsi rândul în aceeași structură. PostgreSQL păstrează rândurile în heap, iar o parcurgere obișnuită a indexului folosește o referință către rând. Diferența poate conta la citiri punctuale, dar PostgreSQL poate evita accesul la heap când interogarea poate fi satisfăcută numai din index și condițiile pentru o astfel de citire sunt îndeplinite.

La actualizări apare o altă diferență: PostgreSQL creează o nouă versiune a rândului și recuperează spațiul ocupat de versiunile devenite inutile prin vacuum. InnoDB păstrează informațiile necesare versiunilor vechi în mecanismul undo. De aceea, un test alcătuit numai din inserări surprinde alt cost decât o sarcină care modifică repetat rânduri existente. Pentru această comparație trebuie păstrată proporția reală dintre citiri, inserări, actualizări și ștergeri, precum și durata în care se măsoară efectul întreținerii datelor.

Cum a inversat lățimea de bandă ordinea într-un test OLTP

În experimentul NVMeVirt, schimbarea lățimii de bandă inversează ordinea dintre PostgreSQL și MariaDB la sarcina OLTP.

În experimentul NVMeVirt, PostgreSQL și MariaDB au rulat o sarcină OLTP pe stocare NVMe emulată: la limita de 250 MiB/s, MariaDB a atins de 2,45 ori debitul de tranzacții al PostgreSQL; fără acea limită, PostgreSQL a atins de 1,82 ori debitul MariaDB. Autorii au folosit sysbench și au variat caracteristicile dispozitivului virtual. Inversarea privește acele motoare, acea sarcină și configurația lor, nu orice instalare MySQL sau PostgreSQL.

Explicația observată în experiment este că debitul PostgreSQL a continuat să crească atunci când dispozitivul a oferit mai multă lățime de bandă, în timp ce MariaDB a folosit mult mai puțin din capacitatea suplimentară. Sensibilitatea la I/O face ca o limită impusă de disc, de mașina virtuală sau de serviciul de stocare să poată cântări în rezultat la fel de mult ca alegerea motorului.

O analiză ulterioară pe NVMeVirt a găsit tot o micșorare a diferenței OLTP când creștea lățimea de bandă, dar nu aceeași inversare: MariaDB a rămas înainte la toate limitele testate, iar mediul atingea cel mult aproximativ 660 MiB/s. Autorii au folosit alte resurse de calcul și o configurație diferită. Prin urmare, cele două rezultate descriu condiții de test distincte; plafonul de I/O este esențial pentru interpretarea lor.

JSON: indexul potrivit depinde de filtre

PostgreSQL indexează căutări variate în JSONB prin GIN, iar MySQL poate indexa o valoare extrasă într-o coloană generată.

În PostgreSQL, un index GIN poate fi creat direct pe o coloană JSONB. Documentația PostgreSQL despre JSONB descrie căutări după chei, conținut și expresii de cale pe care le pot susține clasele de operatori potrivite. Un index pentru întregul document oferă flexibilitate când filtrele variază, însă stochează informații pentru numeroase chei și valori; un index pe o expresie frecvent folosită poate fi mai mic și mai rapid pentru acea căutare.

În MySQL 8.0, o coloană JSON nu este indexată direct. Manualul MySQL pentru JSON descrie indexarea unei coloane generate care extrage o valoare scalară și indexuri multivaloare pentru tablouri JSON. Dacă aplicația filtrează mereu după aceleași căi, aceste indexuri pot răspunde exact nevoii ei. Pentru filtre schimbătoare, proiectarea câte unui index pentru valorile urmărite cere mai multă planificare a schemei.

Comparația devine relevantă când ambele sisteme primesc indexuri adecvate acelorași filtre. Un GIN pe JSONB pus lângă o interogare MySQL fără index corespunzător măsoară și alegerea indexurilor, nu doar diferența dintre motoare. Trebuie urmărit și costul la scriere: indexurile care accelerează căutarea ocupă spațiu și sunt întreținute când datele se schimbă.

Join-urile și analiza cer propria probă

La interogări care reunesc tabele și agregă rezultate, selecția planului poate schimba numărul de rânduri citite și ordinea în care sunt prelucrate. Avantajul posibil al PostgreSQL pentru astfel de sarcini ține de opțiunile planificatorului, însă timpul efectiv depinde de filtre, statistici, indexuri, memorie și dimensiunea datelor. Un rezultat obținut cu toate tabelele în cache spune puțin despre aceeași interogare executată când datele trebuie citite de pe stocare.

În analiza ulterioară a experimentului NVMeVirt, sarcina analitică a fost o interogare cu join-uri dintr-un set de teste TPC-H, pe PostgreSQL și MariaDB. Ea ajută la înțelegerea diferenței dintre tranzacții scurte și interogări ample, dar rămâne o observație despre configurațiile studiate. Pentru o aplicație reală, timpul rapoartelor trebuie judecat separat de debitul cererilor după cheia primară.

Condițiile care trebuie egalizate

Un benchmark util începe cu aceeași muncă pentru ambele sisteme: date cu aceeași distribuție, filtre cu aceeași logică, aceleași coloane returnate și un amestec comparabil de operații. Indexurile trebuie să servească aceleași întrebări, chiar dacă structurile lor sunt diferite. Altfel, diferența de timp poate proveni dintr-un acces la date bine pregătit într-un sistem și absent în celălalt.

Resursele și regulile tranzacțiilor contează la fel de mult: memorie disponibilă, lățime de bandă și latență I/O, concurență, număr de conexiuni și condițiile în care o scriere este considerată confirmată durabil. Trebuie distinsă prima rulare, care citește mai mult de pe stocare, de rulările cu date în cache. O probă suficient de lungă poate surprinde și costurile de curățare a versiunilor vechi, pe care un test foarte scurt le-ar omite.

Decizia se leagă de operația care limitează aplicația: latența unei citiri după identificator, debitul modificărilor, timpul unui join sau durata unui raport. Măsurarea debitului împreună cu latența cererilor lente arată dacă un câștig la numărul total de operații vine cu un timp de răspuns acceptabil. Rezultatul are sens împreună cu sarcina, indexurile și stocarea pe care a fost obținut.

Citește și:

Distribuie:

Abonează-te la newsletter

Primește cele mai noi știri despre Web3, IA și cripto direct în inbox.

0