Differenza prestazionale tra MySQL e PostgreSQL per lo stesso schema / query [chiuso]


20

Sono un DBA principiante e ho esperienza in Microsoft SQL Server ma voglio passare a FLOSS.

Sto avviando un'azienda e sviluppiamo un'app (PHP) con un backend Postgres e abbiamo fatto alcuni test anche a confronto con MySQL. Osserviamo che MySQL è due volte più veloce di PostgreSQL.

Ho fatto un test tangibile delle prestazioni:

  • Stesse colonne nella tabella con tipi di dati di colonna equivalenti.
  • Stesso numero di righe.
  • Stessi indici in entrambi (chiave primaria inclusa).
  • Il carico della CPU è inattivo e la macchina Postgres è decisamente migliore.
  • E la stessa query (ovviamente).

Che cosa sto facendo di sbagliato?

PS: ho letto molti "howtos" sull'ottimizzazione delle prestazioni per i motori di database.
PS (2): stiamo usando InnoDB (un file per tabella) sul database MySQL.


Ciao Mat!

Ho fatto le tre query di selezione comuni (e più difficili).

La domanda sul disco, certamente non è la stessa; In Postgres è un SSD (quasi tre volte più veloce).

Dati cache MySQL:

+------------------------------+----------------------+
| Variable_name                | Value                |
+------------------------------+----------------------+
| binlog_cache_size            | 32768                |
| have_query_cache             | YES                  |
| key_cache_age_threshold      | 300                  |
| key_cache_block_size         | 1024                 |
| key_cache_division_limit     | 100                  |
| max_binlog_cache_size        | 18446744073709547520 |
| query_cache_limit            | 1048576              |
| query_cache_min_res_unit     | 4096                 |
| query_cache_size             | 16777216             |
| query_cache_type             | ON                   |
| query_cache_wlock_invalidate | OFF                  |
| table_definition_cache       | 256                  |
| table_open_cache             | 64                   |
| thread_cache_size            | 8                    |
+------------------------------+----------------------+

Non so come visualizzarlo in PostgreSQL.

Grazie in anticipo.


Ci scusiamo per il mio inglese
Javier Valencia,

(Il tuo inglese va bene.) Hai eseguito test di carico o solo singole query? Potresti mostrare le impostazioni del database che hai usato (specialmente cose come le dimensioni della cache)? (Presumo gli stessi dischi in entrambi i casi?)
Mat

1
Puoi pubblicare la query e il piano di esecuzione di Postgres usando explain analyze. Per rendere più facile la lettura, è possibile caricare il piano per explain.depesz.com
a_horse_with_no_name

1
Se Postgres è in esecuzione su un SSD devi quasi sicuramente sintonizzartipostgresql.conf
a_horse_with_no_name

1
@JavierValencia: se sei stato in grado di risolvere il problema, aggiungi una risposta che descriva ciò che hai fatto in modo che altri possano imparare da quello. Puoi anche accettare la tua risposta per contrassegnare questa domanda come risolta
a_horse_with_no_name

Risposte:


41

MySQL e PostgreSQL sono abbastanza diverse dal punto di vista delle prestazioni. Le tabelle InnoDB e PostgreSQL sono ottimizzate per diversi tipi di query. Comprendere queste differenze è importante per capire come ottenere buone prestazioni da entrambi.

Ad esempio, diamo un'occhiata alla differenza più evidente.

PostgreSQL vs MySQL / InnoDB Struttura della tabella e significato delle prestazioni

In generale, su carichi di lavoro complessi, PostgreSQL sarà più veloce, ma su semplici ricerche di chiavi primarie MySQL con InnoDB sarà più veloce.

Le tabelle PostgreSQL sono tabelle heap. Non è possibile creare una tabella che non sia una tabella heap. Il clustercomando riscrive semplicemente l'heap ordinato da un indice specificato. Gli indici forniscono quindi le posizioni degli heap per le tuple con vari valori. Gli indici non possono essere attraversati in ordine fisico, ma solo in ordine logico, quindi hanno un sacco di I / O su disco casuale durante la lettura sequenziale di una tabella di solito significa un sacco di I / O su disco sequenziale, dato che è possibile leggere una tabella in ordine fisico. L'I / O sequenziale del disco utilizza la cache read-ahead e alcune altre ottimizzazioni a livello di sistema operativo.

Ciò significa che se hai bisogno di una parte significativa dei record o su poche pagine, di solito è più veloce leggere le pagine dal disco. D'altra parte, una ricerca della chiave primaria per una tabella richiede di colpire l'indice, cercare la posizione nel file, quindi premere la tabella di heap ed estrarre il record. Ciò significa un numero di pezzi di I / O su disco casuale.

InnoDB utilizza un approccio diverso. Con InnoDB, la tabella è un indice b-tree con i dati effettivi nel payload dell'indice. Ciò significa che una ricerca della chiave primaria arriva già a estrarre i dati dalla pagina foglia e quindi è necessario un I / O del disco meno casuale. Allo stesso tempo, una scansione dell'indice richiede di attraversare due indici anziché uno, il che significa che l'uso di qualsiasi indice diverso dalla chiave primaria risulta più lento e le scansioni sequenziali sono ancora più lente.

Diagnosi in PostgreSQL

Penso che tu voglia usare qualcosa come:

 EXPLAIN (analyse, buffers, verbose)
 [query];

Ciò fornirà il piano di query, le stime iniziali, i tempi effettivi, l'utilizzo del buffer e molto altro.


4
+1 per EXPLAIN (analisi, buffer, verbose)
karmakaze,

@ChrisTravers grazie per un'ottima risposta! Hai detto: "... le scansioni sequenziali (di InnoDB) sono più lente". Potresti spiegare cosa intendi per scansioni sequenziali in questo contesto?
VB_

Grazie. Modificherò la risposta. Le scansioni "sequenziali" in InnoDB sono in ordine logico indicizzato, quindi hai più I / O casuali e nessun aiuto dalla cache read-ahead.
Chris Travers,

Grazie per la bella risposta Per chiunque sia interessato a postgres all'interno, consiglio questo post: interdb.jp/pg/pgsql01.html Spiega come Postgres memorizza i dati come tabella heap.
hqt
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.