Різниця продуктивності між MySQL та PostgreSQL для тієї ж схеми / запитів [закрито]


20

Я новачок DBA і маю досвід роботи в Microsoft SQL Server, але хочу перейти до FLOSS.

Я запускаю компанію, і ми розробляємо додаток (PHP) із заднім числом Postgres, і ми також зробили кілька тестів порівняно з MySQL. Ми спостерігаємо, що MySQL вдвічі швидший, ніж PostgreSQL.

Я зробив відчутний тест на працездатність:

  • Однакові стовпці таблиці з еквівалентними типами даних стовпців.
  • Однакова кількість рядків.
  • Однакові показники в обох (включений первинний ключ).
  • Навантаження процесора простоює, а машина Postgres - це значно краще.
  • І той самий запит (очевидно).

Що я роблю неправильно?

PS: Я прочитав багато "хаутів" щодо настройки продуктивності для двигунів бази даних.
PS (2): ми використовуємо InnoDB (один файл на таблицю) в базі даних MySQL.


Привіт Мате!

Я зробив три загальні вибіркові (і найскладніші) запити.

Питання про диск, звичайно, це не те саме; У Postgres це SSD (майже три рази найшвидший).

Дані кеша 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                    |
+------------------------------+----------------------+

Я не знаю, як це переглянути в PostgreSQL.

Заздалегідь спасибі.


Вибачте за мою англійську
Хав'єр Валенсія

(Ваша англійська добре.) Ви робили тести на завантаження чи просто окремі запити? Чи могли б ви показати налаштування бази даних, які ви використовували (особливо такі речі, як розміри кеша)? (Однакові диски в обох випадках я припускаю?)
Мат

1
Чи можете ви розмістити запит та план виконання Postgres, використовуючи explain analyze. Щоб полегшити читання, ви можете завантажити план на тлумачення.depesz.com
a_horse_with_no_name

1
Якщо Postgres працює на SSD, вам майже напевно доведеться налаштуватиpostgresql.conf
a_horse_with_no_name

1
@JavierValencia: якщо вам вдалося виправити проблему, додайте відповідь, що описує, що ви зробили, щоб інші могли навчитися цьому. Ви також можете прийняти власну відповідь, щоб позначити це питання як вирішене
a_horse_with_no_name

Відповіді:


41

MySQL і PostgreSQL дуже різняться в продуктивності. Таблиці InnoDB і PostgreSQL оптимізовані для різних типів запитів. Розуміння цих відмінностей важливо для розуміння того, як отримати хороші результати з будь-якого.

Як приклад розглянемо найбільш очевидну різницю.

Структура таблиць PostgreSQL та MySQL / InnoDB та що це означає для продуктивності

Взагалі, на складних робочих навантаженнях PostgreSQL буде швидше, але на простих пошуках первинного ключа MySQL з InnoDB буде швидше.

Таблиці PostgreSQL - це купи купівлі. Немає можливості складати таблицю, яка не є купою таблиці. clusterКоманда просто переписує купу впорядкованої за вказаною індексу. Потім індекси надають місця для кучок з різними значеннями. Індекси не можна переміщувати у фізичному порядку, лише логічний порядок, тому у них багато випадкових вводу-виводу диска під час читання таблиці послідовно зазвичай означає багато послідовних дискових вводу-виводу, оскільки ви можете читати таблицю у фізичному порядку. Послідовний вхід / вивід диска отримує використання кешу вперед та деякої іншої оптимізації на рівні ОС.

Це означає, що якщо вам потрібна значна частина записів або на декількох сторінках, зазвичай швидше просто прочитати сторінки з диска. З іншого боку, пошук первинного ключа для таблиці вимагає натискання на індекс, пошук місця у файлі, потім натисніть на таблицю купи та витягніть запис. Це означає кількість фрагментів вводу / виводу випадкових дисків.

InnoDB використовує інший підхід. У InnoDB таблиця є b-деревом індексу з фактичними даними в корисному навантаженні індексу. Це означає, що пошук первинного ключа вже отримує дані, щоб витягнути дані з листкової сторінки, і тому для цього потрібно менше випадкових вводу-виводу. У той же час сканування індексів вимагає проходження двох індексів замість одного, тобто використання будь-якого індексу, крім первинного ключа, закінчується повільніше, а послідовне сканування все ще повільніше.

Отримання діагнозів у PostgreSQL

Я думаю, ви хочете використовувати щось на кшталт:

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

Це дасть вам план запитів, початкові оцінки, фактичний час, використання буфера та багато іншого.


4
+1 для ПОЯСНЕННЯ (аналіз, буфери, багатослів’я)
karmakaze

@ChrisTravers дякую за чудову відповідь! Ви сказали: "... (InnoDB) послідовне сканування проходить повільніше". Чи можете ви пояснити, що ви маєте на увазі під послідовним скануванням у цьому контексті?
VB_

Спасибі. Я модифікую відповідь. "Послідовні" сканування в InnoDB проходять в індексно-логічному порядку, тому у вас є більше випадкових вводу-виводу та жодної допомоги від кешування вперед.
Кріс Траверс

Дякую за гарну відповідь. Для всіх, хто цікавиться внутрішніми повідомленнями postgres, я рекомендую цей пост: interdb.jp/pg/pgsql01.html Поясніть, як Postgres зберігає дані як таблицю купи.
hqt
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.