Saya punya masalah yang cukup mengganggu. Saya ingin menggunakan INNODB sebagai mesin database utama saya dan menyerah pada MyISAM karena saya membutuhkan yang pertama untuk menggunakan galera-cluster untuk redundansi.
Saya menyalin (uraian berikut) newbb_post
tabel ke tabel baru yang dipanggil newbb_innopost
dan mengubahnya ke InnoDB. Tabel saat ini 5,390,146
masing-masing menampung entri.
Menjalankan pilihan ini pada database yang baru dimulai (jadi tidak ada caching yang terlibat pada saat ini!) Database menghasilkan hasil berikut (menghilangkan output lengkap, harap dicatat bahwa saya bahkan tidak meminta database untuk mengurutkan hasilnya):
PILIH post.postid, post.attach DARI newbb_post AS post WHERE post.threadid = 51506; . . | 5401593 | 0 | | 5401634 | 0 | + --------- + -------- + 62510 baris dalam pengaturan (0,13 detik)
PILIH post.postid, post.attach DARI newbb_innopost AS post WHERE post.threadid = 51506; . . | 5397410 | 0 | | 5397883 | 0 | + --------- + -------- + 62510 baris dalam set (1 mnt 22,19 dtk)
0,13 detik hingga 86,19 detik (!)
Saya bertanya-tanya mengapa ini terjadi. Saya memang membaca beberapa jawaban di Stackexchange yang melibatkan InnoDB dan ada yang menyarankan peningkatan innodb_buffer_pool
ukuran hingga 80% dari RAM yang dipasang. Ini tidak akan menyelesaikan masalah, bahwa permintaan awal untuk ID tertentu akan memakan waktu setidaknya 50x lebih lama dan menghentikan seluruh websever, mengantri koneksi dan permintaan untuk database. Setelah itu cache / buffer mungkin muncul, tetapi ada lebih dari 100.000 utas dalam database ini, sehingga sangat mungkin bahwa cache tidak akan pernah menahan semua permintaan yang relevan untuk dilayani.
Pertanyaan di atas sederhana (tidak ada yang bergabung), dan semua kunci digunakan:
JELASKAN SELECT post.postid, post.attach DARI newbb_innopost AS post WHERE post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- + | id | select_type | meja | ketik | mungkin_kunci | kunci | key_len | ref | baris | Ekstra | + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- + | 1 | SEDERHANA | posting | ref | threadid, threadid_2, threadid_visible_dateline | threadid | 4 | const | 120144 | | + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- +
Ini adalah Tabel MyISAM:
CREATE TABLE `newbb_post` ( `postid` int (10) unsigned NOT NULL AUTO_INCREMENT, `threadid` int (10) unsigned NOT NULL DEFAULT '0', `parentid` int (10) unsigned NOT NULL DEFAULT '0', `username` varchar (100) NOT NULL DEFAULT '', `userid` int (10) unsigned NOT NULL DEFAULT '0', `title` varchar (250) BUKAN NULL DEFAULT '', `dateline` int (10) unsigned NOT NULL DEFAULT '0', mediumtext `pagetext`, `allowmilie` smallint (6) NOT NULL DEFAULT '0', `showsignature` smallint (6) NOT NULL DEFAULT '0', `ipaddress` varchar (15) BUKAN NULL DEFAULT '', `iconid` smallint (5) unsigned NOT NULL DEFAULT '0', `visible` smallint (6) NOT NULL DEFAULT '0', `attach` smallint (5) unsigned NOT NULL DEFAULT '0', `pelanggaran` smallint (5) unsigned NOT NULL DEFAULT '0', `reportthreadid` int (10) unsigned NOT NULL DEFAULT '0', `importthreadid` bigint (20) NOT NULL DEFAULT '0', `importpostid` bigint (20) BUKAN NULL DEFAULT '0', `convert_2_utf8` int (11) TIDAK NULL, `htmlstate` enum ('off', 'on', 'on_nl2br') BUKAN NULL DEFAULT 'on_nl2br', KUNCI UTAMA (`postid`), KUNCI `threadid` (` threadid`, `userid`), KUNCI `importpost_index` (` importpostid`), `Dateline` KUNCI (` dateline`), KUNCI `threadid_2` (` threadid`, `terlihat`,` dateline`), KUNCI `convert_2_utf8` (` dikonversi_2_utf8`), KUNCI `threadid_visible_dateline` (` threadid`, `visible`,` dateline`, `userid`,` postid`), KUNCI `ipaddress` (` ipaddress`), KUNCI `userid` (` userid`, `parentid`), `User_date` KUNCI (` userid`, `dateline`) ) ENGINE = MyISAM AUTO_INCREMENT = 5402802 CHARSET DEFAULT = latin1
dan ini adalah Tabel InnoDB (persis sama):
CREATE TABLE `newbb_innopost` ( `postid` int (10) unsigned NOT NULL AUTO_INCREMENT, `threadid` int (10) unsigned NOT NULL DEFAULT '0', `parentid` int (10) unsigned NOT NULL DEFAULT '0', `username` varchar (100) NOT NULL DEFAULT '', `userid` int (10) unsigned NOT NULL DEFAULT '0', `title` varchar (250) BUKAN NULL DEFAULT '', `dateline` int (10) unsigned NOT NULL DEFAULT '0', mediumtext `pagetext`, `allowmilie` smallint (6) NOT NULL DEFAULT '0', `showsignature` smallint (6) NOT NULL DEFAULT '0', `ipaddress` varchar (15) BUKAN NULL DEFAULT '', `iconid` smallint (5) unsigned NOT NULL DEFAULT '0', `visible` smallint (6) NOT NULL DEFAULT '0', `attach` smallint (5) unsigned NOT NULL DEFAULT '0', `pelanggaran` smallint (5) unsigned NOT NULL DEFAULT '0', `reportthreadid` int (10) unsigned NOT NULL DEFAULT '0', `importthreadid` bigint (20) NOT NULL DEFAULT '0', `importpostid` bigint (20) BUKAN NULL DEFAULT '0', `convert_2_utf8` int (11) TIDAK NULL, `htmlstate` enum ('off', 'on', 'on_nl2br') BUKAN NULL DEFAULT 'on_nl2br', KUNCI UTAMA (`postid`), KUNCI `threadid` (` threadid`, `userid`), KUNCI `importpost_index` (` importpostid`), `Dateline` KUNCI (` dateline`), KUNCI `threadid_2` (` threadid`, `terlihat`,` dateline`), KUNCI `convert_2_utf8` (` dikonversi_2_utf8`), KUNCI `threadid_visible_dateline` (` threadid`, `visible`,` dateline`, `userid`,` postid`), KUNCI `ipaddress` (` ipaddress`), KUNCI `userid` (` userid`, `parentid`), `User_date` KUNCI (` userid`, `dateline`) ) ENGINE = InnoDB AUTO_INCREMENT = 5402802 CHARSET DEFAULT = latin1
Server, dengan RAM 32GB:
Versi server: 10.0.12-MariaDB-1 ~ trusty-wsrep-log distribusi biner mariadb.org, wsrep_25.10.r4002
Jika Anda memerlukan semua pengaturan variabel innodb_, saya dapat melampirkannya pada posting ini.
Memperbarui:
Saya menjatuhkan SEMUA indeks terpisah dari indeks primer, setelah itu hasilnya tampak seperti ini:
. . | 5402697 | 0 | | 5402759 | 0 | + --------- + -------- + 62510 baris di atur (29,74 dtk)
JELASKAN SELECT post.postid, post.attach DARI newbb_innopost AS post WHERE post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + | id | select_type | meja | ketik | mungkin_kunci | kunci | key_len | ref | baris | Ekstra | + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + | 1 | SEDERHANA | posting | SEMUA | NULL | NULL | NULL | NULL | 5909836 | Menggunakan dimana | + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + 1 baris dalam set (0,00 dtk)
Setelah ini saya baru saja menambahkan satu indeks kembali ke mix, threadid, hasilnya adalah sebagai berikut:
. . | 5402697 | 0 | | 5402759 | 0 | + --------- + -------- + 62510 baris di atur (11,58 detik)
JELASKAN SELECT post.postid, post.attach DARI newbb_innopost AS post WHERE post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + | id | select_type | meja | ketik | mungkin_kunci | kunci | key_len | ref | baris | Ekstra | + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + | 1 | SEDERHANA | posting | ref | threadid | threadid | 4 | const | 124622 | | + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + 1 baris dalam set (0,00 dtk)
Anehnya, tanpa indeks yang relevan, pemindaian lengkap hanya membutuhkan waktu 29 detik dibandingkan dengan 88 detik menggunakan indeks (!).
Dengan hanya satu indeks yang disesuaikan dengan sempurna, proses ini masih memerlukan waktu 11 detik - masih terlalu lambat untuk penggunaan di dunia nyata.
Pembaruan 2:
Saya mengatur MySQL (5.5.38-0ubuntu0.14.04.1 (Ubuntu)) di server lain dengan konfigurasi perangkat keras yang sama persis dan database / tabel yang sama persis.
Hasilnya hampir sama, pertama Tabel MyISAM:
. . | 5401593 | 0 | | 5401634 | 0 | + --------- + -------- + 62510 baris dalam set (0,14 detik)
Dan ini adalah hasil dari tabel InnoDB
. . | 5397410 | 0 | | 5397883 | 0 | + --------- + -------- + 62510 baris dalam set (1 mnt 17,63 dtk)
UPDATE 3: isi my.cnf
# File konfigurasi server database MariaDB. # # Anda dapat menyalin file ini ke salah satu dari: # - "/etc/mysql/my.cnf" untuk mengatur opsi global, # - "~ / .my.cnf" untuk mengatur opsi spesifik pengguna. # # Seseorang dapat menggunakan semua opsi panjang yang didukung oleh program. # Jalankan program dengan --help untuk mendapatkan daftar opsi yang tersedia dan dengan # --print-defaults untuk melihat yang benar-benar dimengerti dan digunakan. # # Untuk penjelasan, lihat # http://dev.mysql.com/doc/mysql/en/server-system-variables.html # Ini akan diteruskan ke semua klien mysql # Telah dilaporkan bahwa kata sandi harus diapit dengan tanda centang / tanda kutip # terutama jika mengandung "#" karakter ... # Ingatlah untuk mengedit /etc/mysql/debian.cnf saat mengubah lokasi soket. [klien] port = 3306 socket = /var/run/mysqld/mysqld.sock # Ini adalah entri untuk beberapa program tertentu # Nilai-nilai berikut menganggap Anda memiliki setidaknya 32 juta ram # Ini secara resmi dikenal sebagai [safe_mysqld]. Kedua versi saat ini diuraikan. [mysqld_safe] socket = /var/run/mysqld/mysqld.sock bagus = 0 [mysqld] # # * Pengaturan dasar # user = 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-external-locking # # Alih-alih melewatkan jaringan, default sekarang adalah hanya mendengarkan # localhost yang lebih kompatibel dan tidak kalah aman. bind-address = 127.0.0.1 # # * Mencari setelan # 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 = 16 juta tmp_table_size = 32M max_heap_table_size = 32M # # * MyISAM # # Ini menggantikan skrip startup dan memeriksa tabel MyISAM jika diperlukan # pertama kali mereka disentuh. Jika terjadi kesalahan, buat salinan dan coba perbaikan. myisam_recover = CADANGAN key_buffer_size = 128M # open-files-limit = 2000 table_open_cache = 400 myisam_sort_buffer_size = 512M concurrent_insert = 2 read_buffer_size = 2M read_rnd_buffer_size = 1M # # * Konfigurasi Cache Kueri # # Cache hanya set hasil yang kecil, sehingga kami dapat memuat lebih banyak dalam cache kueri. query_cache_limit = 128K query_cache_size = 64M # untuk pengaturan penulisan yang lebih intensif, atur PERMINTAAN atau MATI #query_cache_type = PERMINTAAN # # * Penebangan dan Replikasi # # Kedua lokasi diputar oleh cronjob. # Perlu diketahui bahwa jenis log ini adalah pembunuh kinerja. # Pada 5.1 Anda dapat mengaktifkan log saat runtime! #general_log_file = /var/log/mysql/mysql.log #general_log = 1 # # Kesalahan logging masuk ke syslog karena /etc/mysql/conf.d/mysqld_safe_syslog.cnf. # Kami ingin tahu tentang kesalahan jaringan dan semacamnya log_warnings = 2 # # Aktifkan log kueri lambat untuk melihat kueri dengan durasi sangat panjang #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-queries-not-using-indexes #log_slow_admin_statements # # Hal berikut ini dapat digunakan untuk memutar ulang log cadangan atau untuk replikasi. # note: jika Anda menyiapkan budak replikasi, lihat README.Debian tentang # pengaturan lain yang mungkin perlu Anda ubah. # server-id = 1 #report_host = master1 #auto_increment_increment = 2 #auto_increment_offset = 1 log_bin = / var / log / mysql / mariadb-bin log_bin_index = /var/log/mysql/mariadb-bin.index # tidak hebat untuk kinerja, tetapi lebih aman #sync_binlog = 1 expire_logs_days = 10 max_binlog_size = 100M # budak #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 #read_only # # Jika aplikasi mendukungnya, sql_mode yang lebih ketat ini mencegah beberapa # kesalahan seperti memasukkan tanggal yang tidak valid, dll. #sql_mode = NO_ENGINE_SUBSTITUTION, TRADITIONAL # # * InnoDB # # InnoDB diaktifkan secara default dengan datafile 10MB di / var / lib / mysql /. # Baca manual untuk opsi terkait InnoDB lainnya. Ada banyak! default_storage_engine = InnoDB # Anda tidak bisa hanya mengubah ukuran file log, memerlukan prosedur khusus #innodb_log_file_size = 50M innodb_buffer_pool_size = 20G innodb_log_buffer_size = 8M innodb_file_per_table = 1 innodb_open_files = 400 innodb_io_capacity = 400 innodb_flush_method = O_DIRECT # # * Fitur keamanan # # Baca manual juga, jika Anda ingin chroot! # chroot = / var / lib / mysql / # # Untuk menghasilkan sertifikat SSL, saya merekomendasikan OpenSSL GUI "tinyca". # # ssl-ca = / etc / mysql / cacert.pem # ssl-cert = / etc / mysql / server-cert.pem # ssl-key = / etc / mysql / server-key.pem [mysqldump] cepat nama-kutipan max_allowed_packet = 16M [mysql] # no-auto-rehash # lebih cepat memulai mysql tetapi tidak ada penyelesaian tab [isamchk] key_buffer = 16 juta # # * PENTING: Pengaturan tambahan yang dapat menggantikan yang dari file ini! # File harus diakhiri dengan '.cnf', jika tidak mereka akan diabaikan. # ! Includedir /etc/mysql/conf.d/
Dan isi dari variabel inno:
MariaDB [(tidak ada)]> TAMPILKAN VARIABEL SEPERTI 'inno%'; + ------------------------------------------- + ----- ------------------- + | Variable_name | Nilai | + ------------------------------------------- + ----- ------------------- + | innodb_adaptive_flushing | ON | | innodb_adaptive_flushing_lwm | 10 | | innodb_adaptive_hash_index | ON | | innodb_adaptive_hash_index_partitions | 1 | | innodb_adaptive_max_sleep_delay | 150000 | | innodb_additional_mem_pool_size | 8388608 | | innodb_api_bk_commit_interval | 5 | | innodb_api_disable_rowlock | OFF | | innodb_api_enable_binlog | OFF | | innodb_api_enable_mdl | OFF | | innodb_api_trx_level | 0 | | innodb_autoextend_increment | 64 | | innodb_autoinc_lock_mode | 1 | | innodb_buffer_pool_dump_at_shutdown | OFF | | innodb_buffer_pool_dump_now | OFF | | innodb_buffer_pool_filename | ib_buffer_pool | | innodb_buffer_pool_inances | 8 | | innodb_buffer_pool_load_abort | OFF | | innodb_buffer_pool_load_at_startup | OFF | | innodb_buffer_pool_load_now | OFF | | innodb_buffer_pool_populate | OFF | | innodb_buffer_pool_size | 21474836480 | | innodb_change_buffer_max_size | 25 | | innodb_change_buffering | semua | | innodb_checksum_algorithm | innodb | | innodb_checksums | ON | | innodb_cleaner_lsn_age_factor | high_checkpoint | | innodb_cmp_per_index_enabled | OFF | | 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 | menegaskan | | innodb_data_file_path | ibdata1: 12M: autoextend | | innodb_data_home_dir | | | innodb_disable_sort_file_cache | OFF | | innodb_doublewrite | ON | | innodb_empty_free_list_algorithm | backoff | | innodb_fake_changes | OFF | | innodb_fast_shutdown | 1 | | innodb_file_format | Antelope | | innodb_file_format_check | ON | | innodb_file_format_max | Antelope | | innodb_file_per_table | ON | | innodb_flush_log_at_timeout | 1 | | innodb_flush_log_at_trx_commit | 1 | | innodb_flush_method | O_DIRECT | | innodb_flush_neighbors | 1 | | innodb_flushing_avg_loops | 30 | | innodb_force_load_corrupted | OFF | | innodb_force_recovery | 0 | | innodb_foreground_preflush | exponential_backoff | | innodb_ft_aux_table | | | innodb_ft_cache_size | 8000000 | | innodb_ft_enable_diag_print | OFF | | innodb_ft_enable_stopword | ON | | innodb_ft_max_token_size | 84 | | innodb_ft_min_token_size | 3 | | innodb_ft_num_word_optimize | 2000 | | innodb_ft_result_cache_limit | 2000000000 | | innodb_ft_server_stopword_table | | | innodb_ft_sort_pll_degree | 2 | | innodb_ft_total_cache_size | 640000000 | | innodb_ft_user_stopword_table | | | innodb_io_capacity | 400 | | innodb_io_capacity_max | 2000 | | innodb_kill_idle_transaction | 0 | | innodb_large_prefix | OFF | | innodb_lock_wait_timeout | 50 | | innodb_locking_fake_changes | ON | | innodb_locks_unsafe_for_binlog | OFF | | innodb_log_arch_dir | ./ | | innodb_log_arch_expire_sec | 0 | | innodb_log_archive | OFF | | innodb_log_block_size | 512 | | innodb_log_buffer_size | 8388608 | | innodb_log_checksum_algorithm | innodb | | innodb_log_compressed_pages | ON | | innodb_log_file_size | 50331648 | | innodb_log_files_in_group | 2 | | innodb_log_group_home_dir | ./ | | innodb_lru_scan_depth | 1024 | | innodb_max_bitmap_file_size | 104857600 | | 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 | 134217728 | | innodb_open_files | 400 | | innodb_optimize_fulltext_only | OFF | | innodb_page_size | 16384 | | innodb_print_all_deadlocks | OFF | | innodb_purge_batch_size | 300 | | innodb_purge_threads | 1 | | innodb_random_read_ahead | OFF | | innodb_read_ahead_threshold | 56 | | innodb_read_io_threads | 4 | | innodb_read_only | OFF | | innodb_replication_delay | 0 | | innodb_rollback_on_timeout | OFF | | innodb_rollback_segments | 128 | | innodb_sched_priority_cleaner | 19 | | innodb_show_locks_held | 10 | | innodb_show_verbose_locks | 0 | | innodb_sort_buffer_size | 1048576 | | innodb_spin_wait_delay | 6 | | innodb_stats_auto_recalc | ON | | innodb_stats_method | nulls_equal | | innodb_stats_on_metadata | OFF | | innodb_stats_persistent | ON | | innodb_stats_persistent_sample_pages | 20 | | innodb_stats_sample_pages | 8 | | innodb_stats_transient_sample_pages | 8 | | innodb_status_output | OFF | | innodb_status_output_locks | OFF | | innodb_strict_mode | OFF | | innodb_support_xa | ON | | innodb_sync_array_size | 1 | | innodb_sync_spin_loops | 30 | | innodb_table_locks | ON | | innodb_thread_concurrency | 0 | | innodb_thread_sleep_delay | 10000 | | innodb_track_changed_pages | OFF | | innodb_undo_directory | . | | innodb_undo_logs | 128 | | innodb_undo_tablespaces | 0 | | innodb_use_atomic_writes | OFF | | innodb_use_fallocate | OFF | | innodb_use_global_flush_log_at_trx_commit | ON | | innodb_use_native_aio | ON | | innodb_use_stacktrace | OFF | | innodb_use_sys_malloc | ON | | innodb_version | 5.6.17-65.0 | | innodb_write_io_threads | 4 | + ------------------------------------------- + ----- ------------------- + 143 baris diatur (0,02 dtk)
Jumlah inti mesin adalah 8, ini a
Intel(R) Xeon(R) CPU E3-1246 v3 @ 3.50GHz
per /proc/cpuinfo
Satu catatan terakhir: Jalankan kueri dengan indeks yang disarankan oleh RolandoMYSQLDBA, dan kueri masing-masing memakan waktu sekitar 11-20. Saya ingin menunjukkan bahwa sangat penting bagi saya (ini adalah tabel utama dari papan buletin) bahwa permintaan pertama tentang pengembalian threadid dalam waktu kurang dari satu detik, karena ada lebih dari 60.000 utas dan google-bot terus merangkak utas ini.
sumber
Jawaban:
QUERY ANDA
Sepintas, kueri itu hanya menyentuh 1,1597% (62510 dari 5390146) dari tabel. Itu harus cepat diberikan kunci distribusi threadid 51506.
PENGECEKAN KENYATAAN
Tidak peduli versi MySQL (Oracle, Percona, MariaDB) mana yang Anda gunakan, tidak satu pun dari mereka yang bisa bertarung dengan satu musuh yang sama-sama mereka miliki: Arsitektur InnoDB.
INDEKS BERKELAS
Harap diingat bahwa setiap entri threadid memiliki kunci primer. Ini berarti bahwa ketika Anda membaca dari indeks, itu harus melakukan pencarian kunci utama dalam ClusteredIndex (secara internal dinamai gen_clust_index) . Dalam ClusteredIndex, setiap halaman InnoDB berisi data dan info indeks KUNCI UTAMA. Lihat posting saya Best of MyISAM dan InnoDB untuk info lebih lanjut.
INDEKSI YANG MENGGUNAKAN
Anda memiliki banyak kekacauan dalam tabel karena beberapa indeks memiliki kolom utama yang sama. MySQL dan InnoDB harus menavigasi melalui indeks kekacauan untuk mendapatkan node BTREE yang dibutuhkan. Anda harus mengurangi kekacauan itu dengan menjalankan yang berikut ini:
Mengapa menghapus indeks ini?
threadid_2
danthreadid_visible_dateline
mulai dengan tiga kolom yang samathreadid_visible_dateline
tidak perlu postid karena KUNCI UTAMA dan tertanamCaching BUFFER
Kolam Buffer InnoDB menyimpan data dan halaman indeks cache. MyISAM hanya menyimpan halaman indeks.
Hanya di area ini saja, MyISAM tidak membuang-buang waktu caching data. Itu karena itu tidak dirancang untuk menyimpan data. InnoDB melakukan cache setiap halaman data dan halaman indeks (dan neneknya) yang disentuhnya. Jika Pool Buffer InnoDB Anda terlalu kecil, Anda bisa caching halaman, membatalkan halaman, dan menghapus halaman semua dalam satu permintaan.
TATA LETAK MEJA
Anda dapat mencukur sebagian ruang dari baris dengan mempertimbangkan
importthreadid
danimportpostid
. Anda memilikinya sebagai BIGINTs. Mereka mengambil 16 byte dalam ClusteredIndex per baris.Anda harus menjalankan ini
Ini akan merekomendasikan tipe data apa kolom ini seharusnya untuk dataset yang diberikan.
KESIMPULAN
MyISAM memiliki jauh lebih sedikit untuk bersaing daripada InnoDB, terutama di bidang caching.
Saat Anda mengungkapkan jumlah RAM (
32GB
) dan versi MySQL (Server version: 10.0.12-MariaDB-1~trusty-wsrep-log mariadb.org binary distribution, wsrep_25.10.r4002
), masih ada potongan lain untuk teka-teki ini yang belum Anda ungkapkan.my.cnf
Jika Anda dapat menambahkan hal-hal ini ke pertanyaan, saya dapat menjelaskan lebih lanjut.
UPDATE 2014-08-28 11:27 EDT
Anda harus meningkatkan threading
Saya akan mempertimbangkan untuk menonaktifkan cache permintaan (Lihat posting saya baru-baru ini Mengapa query_cache_type dinonaktifkan secara default mulai dari MySQL 5.6? )
Saya akan melestarikan Buffer Pool
Tingkatkan utas pembersih (jika Anda melakukan DML pada beberapa tabel)
COBALAH !!!
sumber
@RolandMySQLDBA telah memberikan petunjuk yang tepat untuk menjawab pertanyaan. Masalahnya tampaknya terletak pada kueri dan agar hasilnya dikembalikan, masing-masing bidang tersebut harus dibaca (entah bagaimana dari database).
Saya menjatuhkan semua indeks kecuali
PRIMARY KEY
, dan memasukkan indeks baru ini:ALTER TABLE newbb_innopost ADD INDEX threadid_visible_dateline_index (threadid,visible,dateline,userid,attach,ipaddress);
Tautan ini menjelaskan apa yang terjadi di sini ( mencakup indeks ): Bidang kueri dari kueri yang
postid,attach
sekarang dapat diekstraksi dari kunci itu sendiri. Itu menghemat memeriksa data nyata dan menggunakan I / O ke hard disk.Semua pertanyaan sekarang dijalankan dengan 0,00 detik .. :)
Terima kasih banyak atas bantuan Anda.
Sunting : Masalah mendasar yang sebenarnya tidak terpecahkan, saya hanya mengelak dengan teknik ini. InnoDB membutuhkan beberapa perbaikan serius di bidang ini.
sumber
SQL_NO_CACHE
.Berdasarkan kueri dan tabel Anda, sepertinya Anda adalah data selectikg dari tabel seri waktu. Dengan demikian, mungkin waktu kueri lambat karena Anda memasukkan secara bersamaan?
Jika kedua hal itu benar, daripada mungkin saya sarankan melihat ScaleDB sebagai alternatif? Anda masih menggunakan MariaDB, hanya (mungkin) mesin yang lebih tepat.
http://www.scaledb.com - Beranda http://www.scaledb.com/download-form.php - produk kami
sumber
Kedua mesin akan menjalankan kueri dengan lebih cepat
Ini karena itu akan menjadi indeks "meliputi", dan akan beroperasi dengan cara yang hampir sama (menggunakan indeks BTree).
Juga, saya akan mengatakan bahwa hal ini tidak mungkin untuk baik mesin pada server "dingin":
Silakan gunakan
SQL_NO_CACHE
setiap kali menjalankan timing - kami tidak ingin cache Query mencemari kesimpulan.Pendekatan cepat lainnya (tidak bisa melakukan caching I / O):
Gunakan InnoDB, dan ubah dari
PRIMARY KEY (postid)
menjadiAlasannya adalah bahwa ini akan menyebabkan semua baris yang relevan berdekatan, sehingga membutuhkan lebih sedikit I / O, dll.
INDEX(postid)
Adalah untuk tetapAUTO_INCREMENT
bahagia. Peringatan: Ini mengacaukan semua kunci sekunder - beberapa akan lebih cepat, beberapa akan lebih lambat.sumber
Meskipun tidak secara langsung berlaku untuk @ jollyroger karena dia sudah memiliki pengaturan yang benar, tetapi saya mendapat peningkatan besar mengubah
innodb_buffer_pool_size
70% dari RAM saya seperti yang dijelaskan dalam Mengapa myisam lebih lambat dari InnodbPertama
MyISAM
lambat, tapi oke. KemudianInnoDB
membuat hal-hal buruk, mirip dengan 100x lebih lambat dalam pertanyaan ini dan setelah mengubah pengaturanInnoDB
menjadi 10x lebih cepatMyISAM
.Pengaturan default saya adalah 8MB yang jauh dari sedikit.
sumber