InnoDB 100x'teki basit SELECT'ler neden MyISAM'da olduğundan daha yavaş?


33

Çok can sıkıcı bir sorunum var. INNODB'yi ana veri tabanı motorum olarak kullanmak ve artık yedeklilik için galera-cluster kullanmak için eskiye ihtiyaç duyduğum MyISAM'den vazgeçmek istiyorum.

Ben newbb_posttabloyu ( tabloyu takip eder) yeni bir tabloya kopyaladım newbb_innopostve InnoDB olarak değiştirdim. Tablolar şu anda 5,390,146her birinin girişlerini tutmaktadır .

Bu seçimleri yeni başlatılmış bir veritabanında çalıştırmak (bu noktada önbellekleme yapılmaz!), Veritabanı aşağıdaki sonuçları verir (çıktının tamamen çıkarılması, veritabanından sonuçları sıralamasını bile istemediğime dikkat edin):

Post.postid SEÇİN, post.attach newbb_post FROM WHERE post.threadid = 51506;

.
.
| 5401593 | 0 |
| 5401634 | 0 |
+ --------- + -------- +
Sette 62510 satır (0.13 sn)
Post.postid SELECT, post.attach newbb_innopost FROM WHERE post.threadid = 51506;
.
.
| 5397410 | 0 |
| 5397883 | 0 |
+ --------- + -------- +
Sette 62510 satır (1 dak 22.19 sn)

0,13 saniye - 86,19 saniye (!)

Bunun neden olduğunu merak ediyorum. Burada InnoDB'yi içeren Stackexchange'te bazı cevaplar okudum ve bazıları innodb_buffer_poolkurulu RAM'in% 80'ini arttırdığını gösteriyor . Bu, sorunu çözmeyecek, belirli bir kimliğe yapılan ilk sorgunun en az 50 kat daha uzun süreceği ve tüm webseverleri durduracağı, veritabanı için bağlantıları ve sorguları sıraya sokacağı. Daha sonra önbellek / arabellek devreye girebilir, ancak bu veritabanında 100.000'den fazla iş parçacığı vardır, bu nedenle önbellek, hizmet edilecek tüm ilgili sorguları hiçbir zaman tutmaz.

Yukarıdaki sorgular basittir (birleştirme yok) ve tüm anahtarlar kullanılır:

EXPLAIN SELECT post.postid, post.att newbb_innopost FROM WHERE post.threadid = 51506;
+ ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- +
| id | select_type | masa | türü | possible_keys | anahtar | key_len | ref | satırlar | Ekstra |
+ ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- +
| 1 | BASİT | gönderi | ref | threadid, threadid_2, threadid_visible_dateline | iş parçacığı | 4 | const | 120144 | |
+ ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- +

Bu MyISAM-Tablosu:

CREATE TABLE `newbb_post` (
  `postid` int (10) imzasız DEĞİL NULL AUTO_INCREMENT,
  'threadid` int (10) imzasız DEĞİL NULL DEFAULT' 0 ',
  'parentid' int (10) imzasız DEĞİL NULL VARSAYIM '0',
  `kullanıcı adı` varchar (100) NULL DEĞERLİ DEĞİL '',
  “userid” int (10) imzasız DEĞİL NULL VARSAYIM '0',
  `title` varchar (250) NULL DEFAULT '',
  “dateline” int (10) imzasız DEĞİL NULL VARSAYIM '0',
  pagetext orta metni,
  `letsilie smallint (6) NULL DEĞERLİ DEĞİL '0',
  `showignature` smallint (6) NULL DEĞERLİ DEĞİL '0',
  'ipadresi' varchar (15) NULL DEĞERLİ DEĞİL '',
  `iconid` smallint (5) imzasız DEĞİL NULL DEFAULT '0',
  `visible` smallint (6) NULL DEĞİL DEĞİL '0'
  `attach` smallint (5) işaretsiz NOT NULL DEFAULT '0',
  “ihlal” smallint (5) imzalı DEĞİL NULL DEFAULT '0',
  `intratedid 'int (10) imzasız DEĞİL NULL DEFAULT' 0 ',
  `importthreadid 'bigint (20) NULL DEFAULT' 0 'DEĞİL,
  'importpostid' bigint (20) NULL DEĞERLİ DEĞİL '0',
  converted_2_utf8 int (11) NOT NULL,
  `htmlstate` enum ('kapalı', 'açık', 'on_nl2br') NULL DEFAULT 'on_nl2br' DEĞİL,
  İLK ANAHTAR (`postid '),
  ANAHTAR `threadid` (` threadid ',' userid '),
  ANAHTAR `importpost_index` (` importpostid`),
  ANAHTAR datelin (datelin)
  ANAHTAR `threadid_2` (` threadid ',' görünür ',' dateline '),
  ANAHTAR `converted_2_utf8` (` converted_2_utf8`)
  ANAHTAR `threadid_visible_dateline` (` threadid ',' görünür ',' dateline ',' userid ',' postid '),
  ANAHTAR `ipadresi '(ipadresi),
  ANAHTAR KİMLİK (kullanıcı kimliği, ebeveynlik)
  ANAHTAR `user_date` (userid`, dateline`)
) MOTOR = MyISAM AUTO_INCREMENT = 5402802 VARSAYILAN ÖZELLİKLERİ = latin1

ve bu InnoDB Tablosu (tamamen aynı):

CREATE TABLE `newbb_innopost` (
  `postid` int (10) imzasız DEĞİL NULL AUTO_INCREMENT,
  'threadid` int (10) imzasız DEĞİL NULL DEFAULT' 0 ',
  'parentid' int (10) imzasız DEĞİL NULL VARSAYIM '0',
  `kullanıcı adı` varchar (100) NULL DEĞERLİ DEĞİL '',
  “userid” int (10) imzasız DEĞİL NULL VARSAYIM '0',
  `title` varchar (250) NULL DEFAULT '',
  “dateline” int (10) imzasız DEĞİL NULL VARSAYIM '0',
  pagetext orta metni,
  `letsilie smallint (6) NULL DEĞERLİ DEĞİL '0',
  `showignature` smallint (6) NULL DEĞERLİ DEĞİL '0',
  'ipadresi' varchar (15) NULL DEĞERLİ DEĞİL '',
  `iconid` smallint (5) imzasız DEĞİL NULL DEFAULT '0',
  `visible` smallint (6) NULL DEĞİL DEĞİL '0'
  `attach` smallint (5) işaretsiz NOT NULL DEFAULT '0',
  “ihlal” smallint (5) imzalı DEĞİL NULL DEFAULT '0',
  `intratedid 'int (10) imzasız DEĞİL NULL DEFAULT' 0 ',
  `importthreadid 'bigint (20) NULL DEFAULT' 0 'DEĞİL,
  'importpostid' bigint (20) NULL DEĞERLİ DEĞİL '0',
  converted_2_utf8 int (11) NOT NULL,
  `htmlstate` enum ('kapalı', 'açık', 'on_nl2br') NULL DEFAULT 'on_nl2br' DEĞİL,
  İLK ANAHTAR (`postid '),
  ANAHTAR `threadid` (` threadid ',' userid '),
  ANAHTAR `importpost_index` (` importpostid`),
  ANAHTAR datelin (datelin)
  ANAHTAR `threadid_2` (` threadid ',' görünür ',' dateline '),
  ANAHTAR `converted_2_utf8` (` converted_2_utf8`)
  ANAHTAR `threadid_visible_dateline` (` threadid ',' görünür ',' dateline ',' userid ',' postid '),
  ANAHTAR `ipadresi '(ipadresi),
  ANAHTAR KİMLİK (kullanıcı kimliği, ebeveynlik)
  ANAHTAR `user_date` (userid`, dateline`)
) MOTOR = InnoDB AUTO_INCREMENT = 5402802 VARSAYILAN ÖZELLİKLER = latin1

Sunucu, 32GB RAM ile:

Sunucu sürümü: 10.0.12-MariaDB-1 ~ trusty-wsrep-log mariadb.org ikili dağıtım, wsrep_25.10.r4002

Tüm innodb_ değişkenleri ayarına ihtiyacınız varsa, bunu bu yazıya ekleyebilirim.

Güncelleştirme:

ALL dizinlerini birincil dizin dışında bıraktım, ardından sonuç şöyle göründü:

.
.
| 5402697 | 0 |
| 5402759 | 0 |
+ --------- + -------- +
Set halinde 62510 satır (29.74 sn)
EXPLAIN SELECT post.postid, post.att newbb_innopost FROM WHERE post.threadid = 51506;
+ ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- +
| id | select_type | masa | türü | possible_keys | anahtar | key_len | ref | satırlar | Ekstra |
+ ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- +
| 1 | BASİT | gönderi | TÜM | NULL | NULL | NULL | NULL | 5909836 | Nerede |
+ ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- +
Sette 1 satır (0.00 sn)

Bundan sonra, tekrar karışıma bir indeks ekledim, iş parçacığı, sonuçlar şöyle:

.
.
| 5402697 | 0 |
| 5402759 | 0 |
+ --------- + -------- +
Sette 62510 satır (11.58 sn)
EXPLAIN SELECT post.postid, post.att newbb_innopost FROM WHERE post.threadid = 51506;
+ ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- +
| id | select_type | masa | türü | possible_keys | anahtar | key_len | ref | satırlar | Ekstra |
+ ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- +
| 1 | BASİT | gönderi | ref | iş parçacığı | iş parçacığı | 4 | const | 124622 | |
+ ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- +
Sette 1 satır (0.00 sn)

Garip, ilgili endeksler olmadan, tam taramanın indeksleri (!) Kullanarak 88 saniyeye kıyasla sadece 29 saniye sürdüğü.

Sadece bir tane özel olarak uyarlanmış endeksle tamamlamak için hala 11 saniye sürüyor - herhangi bir gerçek dünya kullanımı için hala çok yavaş.

Güncelleme 2:

MySQL'i (5.5.38-0ubuntu0.14.04.1 (Ubuntu)) başka bir sunucuya aynı donanım yapılandırması ve aynı veritabanı / tablolar ile kurdum.

Sonuçlar hemen hemen aynıdır, ilk önce MyISAM Tablosu:

.
.
| 5401593 | 0 |
| 5401634 | 0 |
+ --------- + -------- +
Sette 62510 satır (0,14 sn)

Ve bu InnoDB tablosunun sonucudur

.
.
| 5397410 | 0 |
| 5397883 | 0 |
+ --------- + -------- +
Sette 62510 satır (1 dak, 17.63 sn)

GÜNCELLEME 3: my.cnf içeriği

# MariaDB veritabanı sunucusu yapılandırma dosyası.
#
# Bu dosyayı şunlardan birine kopyalayabilirsiniz:
# - "/etc/mysql/my.cnf" genel seçeneklerini belirlemek için
# - "~ / .my.cnf", kullanıcıya özel seçenekler belirlemek için.
# 
# Programın desteklediği tüm uzun seçenekleri kullanabilirsiniz.
# Kullanılabilir seçeneklerin bir listesini almak için --help ile programı çalıştırın
# --print-defaults'u hangisinin gerçekten anlayacağını ve kullanacağını görmek için.
#
# Açıklamalar için bakınız
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

# Bu tüm mysql istemcilerine geçecek
# Şifrelerin keneler / tırnak işaretleri arasına alınması gerektiği bildirildi
# escp özellikle eğer "#" karakter içeriyorsa ...
# Soket konumunu değiştirirken /etc/mysql/debian.cnf dosyasını düzenlemeyi unutmayın.
[Müşteri]
port = 3306
socket = /var/run/mysqld/mysqld.sock

# İşte bazı özel programların girişleri
# Aşağıdaki değerler en az 32M koç olduğunu varsayar.

# Bu resmen [safe_mysqld] olarak biliniyordu. Her iki sürüm de şu anda ayrıştırıldı.
[Mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0

[Mysqld]
#
# * Temel Ayarlar
#
kullanıcı = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = / usr
datadir = / var / lib / mysql
tmpdir = / tmp
lc_messages_dir = / usr / share / mysql
lc_messages = en_US
skip-dış kilitleme
#
# Ağ atlama atlamak yerine, varsayılan ayar şimdi yalnızca dinlemek içindir
# Daha uyumlu ve daha az güvenli olmayan localhost.
adres adresi = 127.0.0.1
#
# * İnce ayar
#
max_connections = 100
connect_timeout = 5
wait_timeout = 600
max_allowed_packet = 16M
thread_cache_size = 128
sort_buffer_size = 4M
bulk_insert_buffer_size = 16M
tmp_table_size = 32M
max_heap_table_size = 32M
#
# * MyISAM
#
# Bu başlangıç ​​betiğini değiştirir ve gerekirse MyISAM tablolarını kontrol eder
# ilk dokunuşlarında. Hata durumunda, kopyalayın ve bir onarım deneyin.
myisam_recover = YEDEKLEME
key_buffer_size = 128M
# open-files-limit = 2000
table_open_cache = 400
myisam_sort_buffer_size = 512M
eşzamanlı_insert = 2
read_buffer_size = 2M
read_rnd_buffer_size = 1M
#
# * Sorgu Önbellek Yapılandırması
#
# Önbellek yalnızca küçük sonuç kümeleridir, bu nedenle sorgu önbelleğine daha fazla sığabiliriz.
query_cache_limit = 128K
query_cache_size = 64M
# daha yoğun yazma ayarları için TALEP veya KAPALI olarak ayarlayın
#query_cache_type = DEMAND
#
# * Günlük ve Çoğaltma
#
# Her iki konum da cronjob tarafından döndürülüyor.
# Bu kütük tipinin bir performans öldürücü olduğunu unutmayın.
# 5.1'den itibaren çalışma zamanında günlüğü etkinleştirebilirsiniz!
#general_log_file = /var/log/mysql/mysql.log
#general_log = 1
#
# Hata günlüğü /etc/mysql/conf.d/mysqld_safe_syslog.cnf dosyası nedeniyle syslog'a gider.
#
# ağ hataları ve benzeri hakkında bilmek istiyoruz
log_warnings = 2
#
# Özellikle uzun süreli sorguları görmek için yavaş sorgu günlüğünü etkinleştir
#slow_query_log [= {0 | 1}]
slow_query_log_file = /var/log/mysql/mariadb-slow.log
long_query_time = 10
#log_slow_rate_limit = 1000
log_slow_verbosity = query_plan

# Log sorguları--dizinleri kullanmayan
#log_slow_admin_statements
#
# Yedekleme günlüklerini tekrarlamak veya çoğaltma için aşağıdakiler kullanılabilir.
# not: Bir çoğaltma kölesi ayarlıyorsanız, bkz.
# diğer ayarları değiştirmeniz gerekebilir.
# server-id = 1
#report_host = ana1
#auto_increment_increment = 2
#auto_increment_offset = 1
log_bin = / var / log / mysql / mariadb-bin
log_bin_index = /var/log/mysql/mariadb-bin.index
# performans için fab değil, daha güvenli
#sync_binlog = 1
expire_logs_days = 10
max_binlog_size = 100M
# köleler
#relay_log = / var / log / mysql / relay-bin
#relay_log_index = /var/log/mysql/relay-bin.index
#relay_log_info_file = /var/log/mysql/relay-bin.info
#log_slave_updates
#Sadece oku
#
# Uygulamalar destekliyorsa, bu daha sıkı sql_mode bazılarını önler
# geçersiz tarih eklemek gibi hatalar vs.
#sql_mode = NO_ENGINE_SUBSTITUTION, GELENEKSEL
#
# * InnoDB
#
# InnoDB varsayılan olarak / var / lib / mysql / dizininde 10 MB veri dosyasıyla etkindir.
# InnoDB ile ilgili daha fazla seçenek için kılavuzu okuyun. Çok var!
default_storage_engine = InnoDB
# sadece günlük dosyasının boyutunu değiştiremezsiniz, özel prosedür gerekir
#innodb_log_file_size = 50M
innodb_buffer_pool_size = 20G
innodb_log_buffer_size = 8 milyon
innodb_file_per_table = 1
innodb_open_files = 400
innodb_io_capacity = 400
innodb_flush_method = O_DIRECT
#
# * Güvenlik özellikleri
#
# Eğer chroot istiyorsanız, kılavuzu da okuyun!
# chroot = / var / lib / mysql /
#
# SSL sertifikaları oluşturmak için OpenSSL GUI "tinyca" tavsiye ediyorum.
#
# ssl-ca = / etc / mysql / cacert.pem
# ssl-cert = / etc / mysql / server-cert.pem
# ssl-key = / etc / mysql / server-key.pem



[Mysqldump]
hızlı
alıntı isimler
max_allowed_packet = 16M

[MySQL]
# no-auto-rehash # mysql'in daha hızlı başlatılması ancak sekme tamamlamanın olmaması

[İsamchk]
key_buffer = 16M

#
# * ÖNEMLİ: Bu dosyadakileri geçersiz kılabilecek ek ayarlar!
# Dosyaların '.cnf' ile bitmesi gerekir, aksi takdirde dikkate alınmazlar.
#
! includedir /etc/mysql/conf.d/

Ve inno değişkenlerinin içeriği:

MariaDB [(yok)]> VARIABLES LIKE 'inno%';
+ ------------------------------------------- + ----- ------------------- +
| Değişken_adı | Değer |
+ ------------------------------------------- + ----- ------------------- +
| innodb_adaptive_flushing | AÇIK |
| innodb_adaptive_flushing_lwm | 10 |
| innodb_adaptive_hash_index | AÇIK |
| innodb_adaptive_hash_index_partitions | 1 |
| innodb_adaptive_max_sleep_delay | 150000 |
| innodb_additional_mem_pool_size | 8388608 |
| innodb_api_bk_commit_interval | Instagram Hesabındaki Resim ve Videoları innodb_api_bk_commit_interval 5 |
| innodb_api_disable_rowlock | KAPALI |
| innodb_api_enable_binlog | KAPALI |
| innodb_api_enable_mdl | KAPALI |
| innodb_api_trx_level | 0 |
| innodb_autoextend_increment | 64 |
| innodb_autoinc_lock_mode | Instagram Hesabındaki Resim ve Videoları | 1 |
| innodb_buffer_pool_dump_at_shutdown | Instagram Hesabındaki Resim ve Videoları innodb_buffer_pool_dump_at_shutdown | KAPALI |
| innodb_buffer_pool_dump_now | KAPALI |
| innodb_buffer_pool_filename | ib_buffer_pool |
| innodb_buffer_pool_instances | 8 |
| innodb_buffer_pool_load_abort | KAPALI |
| innodb_buffer_pool_load_at_startup | Instagram Hesabındaki Resim ve Videoları innodb_buffer_pool_load_at_startup KAPALI |
| innodb_buffer_pool_load_now | KAPALI |
| innodb_buffer_pool_populate | KAPALI |
| innodb_buffer_pool_size | 21474836480 |
| innodb_change_buffer_max_size | 25 |
| innodb_change_buffering | hepsi |
| innodb_checksum_algorithm | innodb |
| innodb_checksums | AÇIK |
| Instagram Hesabındaki Resim ve Videoları innodb_cleaner_lsn_age_factor | high_checkpoint |
| innodb_cmp_per_index_enabled | KAPALI |
| innodb_commit_concurrency | 0 |
| innodb_compression_failure_threshold_pct | 5 |
| innodb_compression_level | 6 |
| innodb_compression_pad_pct_max | 50 |
| innodb_concurrency_tickets | 5000 |
| innodb_corrupt_table_action | assert |
| innodb_data_file_path | ibdata1: 12M: otomatik genişleme |
| innodb_data_home_dir | |
| innodb_disable_sort_file_cache | KAPALI |
| innodb_doublewrite | AÇIK |
| innodb_empty_free_list_algorithm | Instagram Hesabındaki Resim ve Videoları innodb_empty_free_list_algorithm geri çekilme |
| innodb_fake_changes | KAPALI |
| innodb_fast_shutdown | 1 |
| innodb_file_format | Antilop |
| innodb_file_format_check | AÇIK |
| innodb_file_format_max | Antilop |
| innodb_file_per_table | AÇIK |
| innodb_flush_log_at_timeout | 1 |
| innodb_flush_log_at_trx_commit | Instagram Hesabındaki Resim ve Videoları innodb_flush_log_at_trx_commit 1 |
| innodb_flush_method | O_DIRECT |
| innodb_flush_neighbors | 1 |
| innodb_flushing_avg_loops | Instagram Hesabındaki Resim ve Videoları innodb_flushing_avg_loops 30 |
| innodb_force_load_corrupted | KAPALI |
| innodb_force_recovery | 0 |
| innodb_foreground_preflush | exponential_backoff |
| innodb_ft_aux_table | Instagram Hesabındaki Resim ve Videoları innodb_ft_aux_table |
| innodb_ft_cache_size | 8000000 |
| innodb_ft_enable_diag_print | KAPALI |
| innodb_ft_enable_stopword | AÇIK |
| innodb_ft_max_token_size | 84 |
| innodb_ft_min_token_size | 3 |
| innodb_ft_num_word_optimize | 2000 |
| innodb_ft_result_cache_limit | Instagram Hesabındaki Resim ve Videoları innodb_ft_result_cache_limit 2000000000 |
| innodb_ft_server_stopword_table | Instagram Hesabındaki Resim ve Videoları innodb_ft_server_stopword_table |
| innodb_ft_sort_pll_degree | 2 |
| innodb_ft_total_cache_size | 640000000 |
| innodb_ft_user_stopword_table | Instagram Hesabındaki Resim ve Videoları | |
| innodb_io_capacity | 400 |
| innodb_io_capacity_max | 2000 |
| innodb_kill_idle_transaction | 0 |
| innodb_large_prefix | KAPALI |
| innodb_lock_wait_timeout | 50 |
| innodb_locking_fake_changes | AÇIK |
| Instagram Hesabındaki Resim ve Videoları innodb_locks_unsafe_for_binlog | KAPALI |
| innodb_log_arch_dir | ./ |
| Instagram Hesabındaki Resim ve Videoları innodb_log_arch_expire_sec | 0 |
| innodb_log_archive | KAPALI |
| innodb_log_block_size | 512 |
| innodb_log_buffer_size | 8388608 |
| Instagram Hesabındaki Resim ve Videoları innodb_log_checksum_algorithm innodb |
| innodb_log_compressed_pages | Instagram Hesabındaki Resim ve Videoları innodb_log_compressed_pages | AÇIK |
| innodb_log_file_size | 50331648 |
| innodb_log_files_in_group | 2 |
| innodb_log_group_home_dir | ./ |
| innodb_lru_scan_depth | Instagram Hesabındaki Resim ve Videoları innodb_lru_scan_depth 1024 |
| innodb_max_bitmap_file_size | 104857600 |
| Instagram Hesabındaki Resim ve Videoları innodb_max_changed_pages | 1000000 |
| innodb_max_dirty_pages_pct | 75 |
| innodb_max_dirty_pages_pct_lwm | 0 |
| innodb_max_purge_lag | 0 |
| innodb_max_purge_lag_delay | 0 |
| innodb_mirrored_log_groups | 1 |
| innodb_monitor_disable | |
| innodb_monitor_enable | |
| innodb_monitor_reset | |
| innodb_monitor_reset_all | |
| innodb_old_blocks_pct | 37 |
| innodb_old_blocks_time | 1000 |
| innodb_online_alter_log_max_size | Instagram Hesabındaki Resim ve Videoları innodb_online_alter_log_max_size 134217728 |
| innodb_open_files | 400 |
| innodb_optimize_fulltext_only | KAPALI |
| innodb_page_size | 16384 |
| innodb_print_all_deadlocks | Instagram Hesabındaki Resim ve Videoları innodb_print_all_deadlocks | KAPALI |
| innodb_purge_batch_size | 300 |
| innodb_purge_threads | 1 |
| innodb_random_read_ahead | KAPALI |
| innodb_read_ahead_threshold | 56 |
| innodb_read_io_threads | 4 |
| innodb_read_only | Instagram Hesabındaki Resim ve Videoları innodb_read_only KAPALI |
| innodb_replication_delay | 0 |
| innodb_rollback_on_timeout | KAPALI |
| innodb_rollback_segments | 128 |
| innodb_sched_priority_cleaner | 19 |
| innodb_show_locks_held | 10 |
| Instagram Hesabındaki Resim ve Videoları innodb_show_verbose_locks 0 |
| innodb_sort_buffer_size | 1048576 |
| innodb_spin_wait_delay | 6 |
| innodb_stats_auto_recalc | Instagram Hesabındaki Resim ve Videoları innodb_stats_auto_recalc AÇIK |
| innodb_stats_method | nulls_equal |
| innodb_stats_on_metadata | KAPALI |
| innodb_stats_persistent | AÇIK |
| Instagram Hesabındaki Resim ve Videoları innodb_stats_persistent_sample_pages | 20 |
| innodb_stats_sample_pages | 8 |
| innodb_stats_transient_sample_pages | Instagram Hesabındaki Resim ve Videoları innodb_stats_transient_sample_pages 8 |
| innodb_status_output | KAPALI |
| innodb_status_output_locks | KAPALI |
| innodb_strict_mode | KAPALI |
| innodb_support_xa | Instagram Hesabındaki Resim ve Videoları innodb_support_xa AÇIK |
| innodb_sync_array_size | 1 |
| innodb_sync_spin_loops | 30 |
| innodb_table_locks | AÇIK |
| innodb_thread_concurrency | 0 |
| innodb_thread_sleep_delay | 10000 |
| innodb_track_changed_pages | KAPALI |
| innodb_undo_directory | . |
| innodb_undo_logs | 128 |
| innodb_undo_tablespaces | 0 |
| Instagram Hesabındaki Resim ve Videoları innodb_use_atomic_writes | KAPALI |
| innodb_use_fallocate | KAPALI |
| Instagram Hesabındaki Resim ve Videoları innodb_use_global_flush_log_at_trx_commit | AÇIK |
| innodb_use_native_aio | AÇIK |
| innodb_use_stacktrace | KAPALI |
| innodb_use_sys_malloc | AÇIK |
| innodb_version | 5.6.17-65.0 |
| innodb_write_io_threads | 4 |
+ ------------------------------------------- + ----- ------------------- +
Sette 143 satır (0.02 sn)

Makinenin çekirdek sayısı 8, bir

Intel(R) Xeon(R) CPU E3-1246 v3 @ 3.50GHz itibariyle /proc/cpuinfo

Son bir not: Sorguları RolandoMYSQLDBA tarafından önerilen endekslere göre koştum ve sorguların her biri yaklaşık 11-20 saniye sürdü. 60.000'den fazla iş parçacığı ve google-botlar sürekli süründüğü için, bir ipucu ile ilgili ilk sorgunun bir saniyeden daha kısa sürede geri dönmesinin benim için çok önemli olduğunu belirtmek isterim. bu konular.


Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
Paul Beyaz GoFundMonica diyor

Yanıtlar:


24

SORULARINIZ

SELECT post.postid, post.attach FROM newbb_innopost AS post WHERE post.threadid = 51506;

İlk bakışta, bu sorgu tablonun sadece% 1.1597'sine (5390146'da 62510) dokunmalıdır. 51506 numaralı vida dişi anahtar dağılımı hızlı bir şekilde yapılmalıdır.

GERÇEKLİK KONTROLÜ

Hangi MySQL sürümünü (Oracle, Percona, MariaDB) kullanırsanız kullanın, hiçbiri ortak olan bir düşmana karşı savaşamaz: InnoDB Mimarisi.

InnoDB Mimarisi

KÜMELENMİŞ ENDEKS

Lütfen her konu girişinde ekli bir anahtar bulunduğunu unutmayın. Bu, dizinden okuduğunuzda, ClusteredIndex (dahili olarak gen_clust_index olarak adlandırılan) içinde birincil anahtar araması yapması gerektiği anlamına gelir . ClusteredIndex'te her InnoDB sayfası hem veri hem de PRIMARY KEY dizin bilgisini içerir. Daha fazla bilgi için "MyISAM ve InnoDB Best" yazımı görün .

REDUNDANT ENDEKSLERİ

Tabloda çok fazla karmaşa var, çünkü bazı indekslerde aynı sütunlar var. MySQL ve InnoDB, ihtiyaç duyulan BTREE düğümlerine ulaşmak için endeks karmaşasından geçmelidir. Aşağıdakileri çalıştırarak bu karmaşayı azaltmalısınız:

ALTER TABLE newbb_innopost
    DROP INDEX threadid,
    DROP INDEX threadid_2,
    DROP INDEX threadid_visible_dateline,
    ADD INDEX threadid_visible_dateline_index (`threadid`,`visible`,`dateline`,`userid`)
;

Neden bu endeksleri soyun?

  • İlk üç dizin diş ipliği ile başlar
  • threadid_2ve threadid_visible_datelineaynı üç sütunla başla
  • threadid_visible_dateline PRIMARY KEY ve gömülü olduğu için postid kullanmaz

Tampon tamponlama

InnoDB Buffer Pool, verileri ve dizin sayfalarını önbelleğe alır. MyISAM yalnızca dizin sayfalarını önbelleğe alır.

Sadece bu alanda, MyISAM, verileri önbelleğe almak için zaman kaybetmez. Çünkü verileri önbelleğe almak için tasarlanmadı. InnoDB dokunduğu her veri sayfasını ve indeks sayfasını (ve büyük annesi) önbelleğe alır. InnoDB Tampon Havuzunuz çok küçükse, sayfaları önbelleğe alıyor, sayfaları geçersiz kılıyor ve tek bir sorguda tüm sayfaları kaldırıyor olabilirsiniz.

TABLO LAYOUT

Sen dikkate alarak satırdan bazı mekanın tıraş olabilir importthreadidve importpostid. Onlara BIGINTs olarak sahipsin. ClusteredIndex satırında 16 bayt alırlar.

Bunu çalıştırmalısın

SELECT importthreadid,importpostid FROM newbb_innopost PROCEDURE ANALYSE();

Bu, bu sütunların verilen veri kümesi için hangi veri türlerinin olması gerektiğini önerecektir.

SONUÇ

MyISAM'ın özellikle önbellekleme alanında InnoDB'den daha az uğraşıyor.

RAM ( 32GB) ve MySQL ( Server version: 10.0.12-MariaDB-1~trusty-wsrep-log mariadb.org binary distribution, wsrep_25.10.r4002) sürümlerini ortaya çıkarırken , bu bulmacanın açığa çıkarmamış başka parçaları da var.

  • InnoDB ayarları
  • Çekirdek Sayısı
  • Diğer ayarlar my.cnf

Bunları soruya ekleyebilirseniz, daha fazla ayrıntıya girebilirim.

GÜNCELLEME 2014-08-28 11:27 EDT

Diş açmayı arttırmalısın

innodb_read_io_threads = 64
innodb_write_io_threads = 16
innodb_log_buffer_size = 256M

Sorgu önbelleğini devre dışı bırakmayı düşünürdüm (Son gönderime bakın Neden query_cache_type varsayılan olarak MySQL 5.6'dan başlatılmalı? )

query_cache_size = 0

Buffer Pool’u koruyacağım

innodb_buffer_pool_dump_at_shutdown=1
innodb_buffer_pool_load_at_startup=1

Temizleme iş parçacıklarını artırın (birden fazla tabloda DML yaparsanız)

innodb_purge_threads = 4

BİR ŞANS VER !!!


InnoDB'nin saf hız testinde daha yavaş olması gerektiğini biliyorum, fakat bu ölçüde? MySQL ekibinin bu açığı kapatmak için çok çalıştığını okudum. Hala ~ 100 kat artışla uğraşıyoruz! Soru - bu nitelikteki sorguların "doğrudan" kümelenmemiş bir B-ağacı indeksi ile (yani PK verilerini içermeyen) daha iyi hizmet edileceğini mi söylüyorsunuz? Öyleyse, bu neden / uygulanmadı / uygulanmadı? OP'nin gerektirdiği işlevsellik kesinlikle marjinal bir kullanım örneği değildir.
Vérace

Bu resmin tam boyutlu sürümüne bir link ekleyebilir misiniz? Bazı parçaların okunması zor :-)
sulu

@RolandMySQLDBA bilgi için teşekkürler - İnşallah 100x yavaşlamanın InnoDB için "normal" olduğunu önermiyorsunuzdur ... 2x veya 3x ile yaşayabilirim, ama 100x çok fazla. İstediğim gibi sorumu eksik bilgileri ekledim :) Şimdiye kadarki açıklamalar için teşekkürler! Makinenin çekirdek sayısı 8'dir.
39'da jollyroger


1
Yardımınız için çok teşekkürler @RolandoMySQLDBA, ne yazık ki bu son tweaks bile yardımcı olmadı ve InnoDB'nin tamamlanması yaklaşık 11-20 saniye sürüyor. Cevabınıza dayanarak bir şey denedim - tüm endeksleri düşürüp bir örtü endeksi oluşturdum. Bu çok yardımcı oldu. İndeksleri açıklamasanız bu çözümü bulamazdım. Cevabınızı kontrol edip kendim ne yaptığımı açıklayan bir cevap yazacağım :)
jollyroger

7

@RolandMySQLDBA soruyu cevaplamak için doğru ipucu verdi. Sorun sorguda yatmaktadır ve sonuçların geri verilmesi için bu alanların her birinin okunması gerekir (bir şekilde veritabanından).

Tüm dizinleri düştüm PRIMARY KEY, ancak yeni dizini ekledim:

ALTER TABLE newbb_innopost ADD INDEX threadid_visible_dateline_index (threadid,visible,dateline,userid,attach,ipaddress);

Bu bağlantı burada ne olduğunu açıklıyor ( indeksini kapsayan ): Sorgunun sorgulanan alanları postid,attachşimdi anahtarın içinden çıkarılabilir. Bu, gerçek verilerin kontrol edilmesini ve G / Ç kullanımının sabit diske kaydedilmesini önler.

Tüm sorgular şimdi 0.00 saniye ile çalışıyor .. :)

Yardımlarınız için çok teşekkür ederim.

Düzenleme : Asıl temel sorun çözülmedi, ben sadece bu teknikle atladım. InnoDB'nin bu alanda bazı ciddi düzeltmeler yapması gerekiyor.


aynı sorunla karşı karşıyayım. myisma sorgusu 0,01 saniye sürer, innodb ise 60 saniye sürer, önerilerinizi deneyebilirsiniz.
AMB

@ AMB - 0.01s, Sorgu önbelleği gibi kokuyor; ile tekrar zaman SQL_NO_CACHE.
Rick James,

0

Sorgunuza ve tablonuza göre, bir zaman serisi tablosundan veri seçtiniz. Gibi, aynı anda ekleyerek sorgu süresi yavaş olabilir?

Bu iki şey doğruysa, alternatif olarak ScaleDB'ye bakmayı önerebilir miyim? Hala MariaDB'de olacaksın, sadece (belki) daha uygun bir motor.

http://www.scaledb.com - Anasayfa http://www.scaledb.com/download-form.php - Ürünümüz


2
Ana sürümün ücretsiz olmadığını da eklemelisiniz.
ypercubeᵀᴹ

0

Her iki motor da sorguyu daha hızlı çalıştıracak

INDEX(threadid, attach, postid)

Bunun nedeni “örtücü” bir endeks olacak ve neredeyse aynı şekilde çalışacak (BTree endeksini kullanarak).

Ayrıca, bunun "soğuk" bir sunucudaki her iki motor için de mümkün olmadığını söyleyeceğim :

62510 rows in set (0.13 sec)

Lütfen SQL_NO_CACHEne zaman çalışırsanız çalışın - Sorgu önbelleğinin sonuçları kirletmesini istemeyiz.

Bir başka hızlı yaklaşım (G / Ç önbelleğe almanın ne olursa olsun):

InnoDB kullanın ve PRIMARY KEY (postid)ile

PRIMARY KEY(threadid, postid),
INDEX(postid)

Bunun nedeni, bu suretle, vb az I / O'yu gerektiren tüm ilgili satırlar bitişik olmasına neden olacaktır INDEX(postid)tutmaktır AUTO_INCREMENTmutlu. Uyarı: Bu, tüm ikincil tuşlarla uğraşır - bazıları daha hızlı, bazıları daha yavaş olacaktır.


0

Her ne kadar doğru ayarlara sahip olduğundan dolayı doğrudan jollyroger için geçerli olmamasına rağmen innodb_buffer_pool_size, neden myisam Innodb'dan daha yavaş?

İlk MyISAMyavaştı ama tamam. Sonra InnoDB, bu sorudaki 100 kat daha yavaş olan şeyleri daha da kötüleştirdi ve ayar değiştirildikten InnoDBsonra 10 kat daha hızlı oldu MyISAM.

Varsayılan ayarım 8 MB'tı, ki bu çok azdı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.