У меня довольно неприятная проблема. Я хочу использовать INNODB в качестве основного механизма базы данных и отказаться от MyISAM, так как мне нужен первый для использования galera-cluster для избыточности.
Я скопировал (описание следует) newbb_post
таблицу в новую таблицу с именем newbb_innopost
и изменил ее на InnoDB. Таблицы в настоящее время содержат 5,390,146
записи каждый.
Выполнение этих выборок в только что запущенной базе данных (так что к этому моменту кэширование не требуется!) База данных дает следующие результаты (пропуская полный вывод, обратите внимание, что я даже не прошу базу данных отсортировать результаты):
ВЫБЕРИТЕ post.postid, post.attach ОТ newbb_post AS post ГДЕ post.threadid = 51506; , , | 5401593 | 0 | | 5401634 | 0 | + --------- + -------- + 62510 рядов в наборе (0,13 с)
ВЫБЕРИТЕ post.postid, post.attach ОТ newbb_innopost КАК post, ГДЕ post.threadid = 51506; , , | 5397410 | 0 | | 5397883 | 0 | + --------- + -------- + 62510 рядов в наборе (1 мин 22,19 с)
0,13 секунды до 86,19 секунды (!)
Мне интересно, почему это происходит. Я прочитал некоторые ответы здесь на Stackexchange с участием InnoDB, а некоторые предлагают увеличить innodb_buffer_pool
размер до 80% установленной оперативной памяти. Это не решит проблему, так как первоначальный запрос к определенному идентификатору займет не менее 50 раз и остановит весь веб-сервер, ставя в очередь соединения и запросы к базе данных. После этого может сработать кеш / буфер, но в этой базе данных более 100 000 потоков, поэтому весьма вероятно, что кеш никогда не будет содержать все соответствующие запросы, которые будут обслуживаться.
Вышеприведенные запросы просты (без объединений), и используются все ключи:
ОБЪЯСНИТЬ ВЫБРАТЬ post.postid, post.attach ОТ newbb_innopost КАК post, ГДЕ post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- + | id | select_type | стол | тип | возможные_ключи | ключ | key_len | ref | строки | Extra | + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- + | 1 | ПРОСТО | пост | ref | threadid, threadid_2, threadid_visible_dateline | нить | 4 | конст | 120144 | | + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- +
Это MyISAM-таблица:
CREATE TABLE `newbb_post` ( `postid` int (10) без знака NOT NULL AUTO_INCREMENT, `threadid` int (10) unsigned NOT NULL DEFAULT '0', `parentid` int (10) без знака NOT NULL ПО УМОЛЧАНИЮ '0', `username` varchar (100) NOT NULL DEFAULT '', `userid` int (10) unsigned NOT NULL DEFAULT '0', `title` varchar (250) NOT NULL DEFAULT '', `dateline` int (10) unsigned NOT NULL DEFAULT '0', `pagetext` mediumtext, `allowmilie` smallint (6) NOT NULL DEFAULT '0', `showignature` smallint (6) NOT NULL DEFAULT '0', `ipaddress` varchar (15) NOT NULL DEFAULT '', `iconid` smallint (5) без знака NOT NULL DEFAULT '0', `visible` smallint (6) NOT NULL DEFAULT '0', `attach` smallint (5) unsigned NOT NULL DEFAULT '0', `нарушение` smallint (5) без знака NOT NULL ПО УМОЛЧАНИЮ '0', reportthreadid int (10) unsigned NOT NULL DEFAULT '0', importthreadid` bigint (20) NOT NULL DEFAULT '0', `importpostid` bigint (20) NOT NULL DEFAULT '0', `convert_2_utf8` int (11) NOT NULL, `htmlstate` enum ('off', 'on', 'on_nl2br') NOT NULL DEFAULT 'on_nl2br', ПЕРВИЧНЫЙ КЛЮЧ (`postid`), KEY `threadid` (` threadid`, `userid`), KEY `importpost_index` (` importpostid`), KEY `dateline` (` даталайн`), KEY `threadid_2` (` threadid`, `visible`,` dateline`), KEY `преобразованный_2_utf8` (` преобразованный_2_utf8`), KEY `threadid_visible_dateline` (` threadid`, `visible`,` dateline`, `userid`,` postid`), КЛЮЧ `ipaddress` (` ipaddress`), КЛЮЧ `userid` (` userid`, `parentid`), KEY `user_date` (` userid`, `dateline`) ) ENGINE = MyISAM AUTO_INCREMENT = 5402802 CHARSET ПО УМОЛЧАНИЮ = латиница 1
и это таблица InnoDB (она точно такая же):
CREATE TABLE `newbb_innopost` ( `postid` int (10) без знака NOT NULL AUTO_INCREMENT, `threadid` int (10) unsigned NOT NULL DEFAULT '0', `parentid` int (10) без знака NOT NULL ПО УМОЛЧАНИЮ '0', `username` varchar (100) NOT NULL DEFAULT '', `userid` int (10) unsigned NOT NULL DEFAULT '0', `title` varchar (250) NOT NULL DEFAULT '', `dateline` int (10) unsigned NOT NULL DEFAULT '0', `pagetext` mediumtext, `allowmilie` smallint (6) NOT NULL DEFAULT '0', `showignature` smallint (6) NOT NULL DEFAULT '0', `ipaddress` varchar (15) NOT NULL DEFAULT '', `iconid` smallint (5) без знака NOT NULL DEFAULT '0', `visible` smallint (6) NOT NULL DEFAULT '0', `attach` smallint (5) unsigned NOT NULL DEFAULT '0', `нарушение` smallint (5) без знака NOT NULL ПО УМОЛЧАНИЮ '0', reportthreadid int (10) unsigned NOT NULL DEFAULT '0', importthreadid` bigint (20) NOT NULL DEFAULT '0', `importpostid` bigint (20) NOT NULL DEFAULT '0', `convert_2_utf8` int (11) NOT NULL, `htmlstate` enum ('off', 'on', 'on_nl2br') NOT NULL DEFAULT 'on_nl2br', ПЕРВИЧНЫЙ КЛЮЧ (`postid`), KEY `threadid` (` threadid`, `userid`), KEY `importpost_index` (` importpostid`), KEY `dateline` (` даталайн`), KEY `threadid_2` (` threadid`, `visible`,` dateline`), KEY `преобразованный_2_utf8` (` преобразованный_2_utf8`), KEY `threadid_visible_dateline` (` threadid`, `visible`,` dateline`, `userid`,` postid`), КЛЮЧ `ipaddress` (` ipaddress`), КЛЮЧ `userid` (` userid`, `parentid`), KEY `user_date` (` userid`, `dateline`) ) ENGINE = InnoDB AUTO_INCREMENT = 5402802 CHARSET ПО УМОЛЧАНИЮ = латиница 1
Сервер с 32 ГБ оперативной памяти:
Версия сервера: 10.0.12-MariaDB-1 ~ бинарный дистрибутив trusty-wsrep-log mariadb.org, wsrep_25.10.r4002
Если вам нужна настройка всех переменных innodb_, я могу прикрепить это к этому посту.
Обновить:
Я отбросил ВСЕ индексы отдельно от первичного индекса, после чего результат выглядел так:
, , | 5402697 | 0 | | 5402759 | 0 | + --------- + -------- + 62510 рядов в наборе (29,74 с)
ОБЪЯСНИТЬ ВЫБРАТЬ post.postid, post.attach ОТ newbb_innopost КАК post, ГДЕ post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + | id | select_type | стол | тип | возможные_ключи | ключ | key_len | ref | строки | Extra | + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + | 1 | ПРОСТО | пост | ВСЕ | NULL | NULL | NULL | NULL | 5909836 | Используя где | + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + 1 ряд в наборе (0,00 сек)
После этого я просто добавил один индекс обратно в mix, threadid, результаты были следующими:
, , | 5402697 | 0 | | 5402759 | 0 | + --------- + -------- + 62510 рядов в наборе (11,58 сек)
ОБЪЯСНИТЬ ВЫБРАТЬ post.postid, post.attach ОТ newbb_innopost КАК post, ГДЕ post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + | id | select_type | стол | тип | возможные_ключи | ключ | key_len | ref | строки | Extra | + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + | 1 | ПРОСТО | пост | ref | нить | нить | 4 | конст | 124622 | | + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + 1 ряд в наборе (0,00 сек)
Странно, что без каких-либо соответствующих индексов полное сканирование заняло всего 29 секунд по сравнению с 88 секундами с использованием индексов (!).
Имея только один идеально настроенный индекс, он по-прежнему занимает 11 секунд, что слишком медленно для любого реального использования.
Обновление 2:
Я устанавливаю MySQL (5.5.38-0ubuntu0.14.04.1 (Ubuntu)) на другом сервере с точно такой же конфигурацией оборудования и точно такой же базой данных / таблицами.
Результаты практически одинаковы, сначала MyISAM Table:
, , | 5401593 | 0 | | 5401634 | 0 | + --------- + -------- + 62510 рядов в наборе (0,14 с)
И это результат таблицы InnoDB
, , | 5397410 | 0 | | 5397883 | 0 | + --------- + -------- + 62510 рядов в наборе (1 мин 17,63 сек)
ОБНОВЛЕНИЕ 3: содержимое my.cnf
# Файл конфигурации сервера базы данных MariaDB. # # Вы можете скопировать этот файл на один из: # - "/etc/mysql/my.cnf", чтобы установить глобальные параметры, # - "~ / .my.cnf", чтобы установить пользовательские параметры. # # Можно использовать все длинные опции, которые поддерживает программа. # Запустите программу с --help, чтобы получить список доступных опций и с # --print-defaults, чтобы увидеть, что он на самом деле понимает и использует. # # Для объяснения см. # http://dev.mysql.com/doc/mysql/en/server-system-variables.html # Это будет передано всем клиентам MySQL # Сообщалось, что пароли должны быть заключены в галочки / кавычки # особенно, если они содержат символы "#" ... # Не забудьте отредактировать /etc/mysql/debian.cnf при изменении местоположения сокета. [Клиент] порт = 3306 socket = /var/run/mysqld/mysqld.sock # Вот записи для некоторых конкретных программ # Следующие значения предполагают, что у вас есть как минимум 32M оперативной памяти # Это было формально известно как [safe_mysqld]. Обе версии в данный момент анализируются. [Mysqld_safe] socket = /var/run/mysqld/mysqld.sock хороший = 0 [ТуздЫ] # # * Основные настройки # user = mysql pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock порт = 3306 basedir = / usr datadir = / var / lib / mysql tmpdir = / tmp lc_messages_dir = / usr / share / mysql lc_messages = en_US пропуск внешнего замок # # Вместо пропуска сети по умолчанию теперь слушать только на # localhost, который более совместим и не менее безопасен. bind-address = 127.0.0.1 # # * Тонкая настройка # 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 # # Это заменяет скрипт запуска и проверяет таблицы MyISAM при необходимости # в первый раз они тронуты. В случае ошибки сделайте копию и попробуйте восстановить. myisam_recover = BACKUP 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 # # * Конфигурация кеша запросов # # Кэшировать только крошечные наборы результатов, поэтому мы можем разместить больше в кеше запросов. query_cache_limit = 128K query_cache_size = 64M # для более интенсивных настроек записи, установите на DEMAND или OFF #query_cache_type = DEMAND # # * Ведение журнала и репликация # # Обе локации вращаются cronjob. # Имейте в виду, что этот тип журнала снижает производительность. # Начиная с 5.1 вы можете включить журнал во время выполнения! #general_log_file = /var/log/mysql/mysql.log #general_log = 1 # # Журнал ошибок идет в системный журнал из-за /etc/mysql/conf.d/mysqld_safe_syslog.cnf. # # мы хотим знать о сетевых ошибках и тому подобном log_warnings = 2 # # Включить медленный журнал запросов, чтобы увидеть запросы с особенно большой продолжительностью #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_slow_admin_statements # # Следующее может быть использовано как для простого воспроизведения журналов резервного копирования, так и для репликации. # примечание: если вы настраиваете ведомое устройство репликации, см. README.Debian о # другие настройки, которые вам может понадобиться изменить. # 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 # не потрясающе для производительности, но безопаснее #sync_binlog = 1 expire_logs_days = 10 max_binlog_size = 100M # рабов #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 # # Если приложения поддерживают это, этот более строгий sql_mode предотвращает некоторые # ошибки, такие как вставка неверных дат и т. д. #sql_mode = NO_ENGINE_SUBSTITUTION, TRADITIONAL # # * InnoDB # # InnoDB включен по умолчанию с файлом данных 10 МБ в / var / lib / mysql /. # Прочтите руководство, чтобы узнать больше об InnoDB. Здесь очень много! default_storage_engine = InnoDB # Вы не можете просто изменить размер файла журнала, требуется специальная процедура #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 # # * Функции безопасности # # Прочтите руководство, если вы хотите chroot! # chroot = / var / lib / mysql / # # Для генерации SSL-сертификатов я рекомендую графический интерфейс OpenSSL "tinyca". # # ssl-ca = / etc / mysql / cacert.pem # ssl-cert = / etc / mysql / server-cert.pem # ssl-key = / etc / mysql / server-key.pem [ТуздЫшпр] быстро цитата-имена max_allowed_packet = 16M [MySQL] # no-auto-rehash # более быстрый запуск mysql, но не завершение табуляции [Isamchk] key_buffer = 16M # # * ВАЖНО: Дополнительные настройки, которые могут переопределить те из этого файла! # Файлы должны заканчиваться на «.cnf», иначе они будут проигнорированы. # ! includesir /etc/mysql/conf.d/
И содержимое переменных inno:
MariaDB [(none)]> SHOW VARIABLES LIKE 'inno%'; + ------------------------------------------- + ----- ------------------- + | Переменное_имя | Значение | + ------------------------------------------- + ----- ------------------- + | 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 | ВЫКЛ | | innodb_api_enable_binlog | ВЫКЛ | | innodb_api_enable_mdl | ВЫКЛ | | innodb_api_trx_level | 0 | | innodb_autoextend_increment | 64 | | innodb_autoinc_lock_mode | 1 | | innodb_buffer_pool_dump_at_shutdown | ВЫКЛ | | innodb_buffer_pool_dump_now | ВЫКЛ | | innodb_buffer_pool_filename | ib_buffer_pool | | innodb_buffer_pool_instances | 8 | | innodb_buffer_pool_load_abort | ВЫКЛ | | innodb_buffer_pool_load_at_startup | ВЫКЛ | | innodb_buffer_pool_load_now | ВЫКЛ | | innodb_buffer_pool_populate | ВЫКЛ | | innodb_buffer_pool_size | 21474836480 | | innodb_change_buffer_max_size | 25 | | innodb_change_buffering | все | | innodb_checksum_algorithm | Иннодб | | innodb_checksums | ON | | innodb_cleaner_lsn_age_factor | high_checkpoint | | innodb_cmp_per_index_enabled | ВЫКЛ | | 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 | утверждать | | innodb_data_file_path | ibdata1: 12M: автоматическое расширение | | innodb_data_home_dir | | | innodb_disable_sort_file_cache | ВЫКЛ | | innodb_doublewrite | ON | | innodb_empty_free_list_algorithm | откат | | innodb_fake_changes | ВЫКЛ | | innodb_fast_shutdown | 1 | | innodb_file_format | Антилопа | | innodb_file_format_check | ON | | innodb_file_format_max | Антилопа | | 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 | ВЫКЛ | | innodb_force_recovery | 0 | | innodb_foreground_preflush | exponential_backoff | | innodb_ft_aux_table | | | innodb_ft_cache_size | 8000000 | | innodb_ft_enable_diag_print | ВЫКЛ | | 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 | ВЫКЛ | | innodb_lock_wait_timeout | 50 | | innodb_locking_fake_changes | ON | | innodb_locks_unsafe_for_binlog | ВЫКЛ | | innodb_log_arch_dir | ./ | | innodb_log_arch_expire_sec | 0 | | innodb_log_archive | ВЫКЛ | | innodb_log_block_size | 512 | | innodb_log_buffer_size | 8388608 | | innodb_log_checksum_algorithm | Иннодб | | 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 | ВЫКЛ | | innodb_page_size | 16384 | | innodb_print_all_deadlocks | ВЫКЛ | | innodb_purge_batch_size | 300 | | innodb_purge_threads | 1 | | innodb_random_read_ahead | ВЫКЛ | | innodb_read_ahead_threshold | 56 | | innodb_read_io_threads | 4 | | innodb_read_only | ВЫКЛ | | innodb_replication_delay | 0 | | innodb_rollback_on_timeout | ВЫКЛ | | 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 | ВЫКЛ | | innodb_stats_persistent | ON | | innodb_stats_persistent_sample_pages | 20 | | innodb_stats_sample_pages | 8 | | innodb_stats_transient_sample_pages | 8 | | innodb_status_output | ВЫКЛ | | innodb_status_output_locks | ВЫКЛ | | innodb_strict_mode | ВЫКЛ | | 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 | ВЫКЛ | | innodb_undo_directory | , | | innodb_undo_logs | 128 | | innodb_undo_tablespaces | 0 | | innodb_use_atomic_writes | ВЫКЛ | | innodb_use_fallocate | ВЫКЛ | | innodb_use_global_flush_log_at_trx_commit | ON | | innodb_use_native_aio | ON | | innodb_use_stacktrace | ВЫКЛ | | innodb_use_sys_malloc | ON | | innodb_version | 5.6.17-65.0 | | innodb_write_io_threads | 4 | + ------------------------------------------- + ----- ------------------- + 143 ряда в наборе (0,02 сек)
Количество ядер машины составляет 8, это
Intel(R) Xeon(R) CPU E3-1246 v3 @ 3.50GHz
по состоянию на /proc/cpuinfo
Последнее замечание: выполнялись запросы с индексами, предложенными RolandoMYSQLDBA, и каждый запрос занимал около 11-20 секунд каждый. Я хочу отметить, что для меня очень важно (это основная таблица доски объявлений), чтобы первый запрос о threadid возвращался менее чем за секунду, так как существует более 60 000 потоков и Google-боты постоянно сканируют эти темы.
источник
Ответы:
ВАШ ЗАПРОС
На первый взгляд этот запрос должен касаться только 1,1597% (62510 из 5390146) таблицы. Это должно быть быстро, учитывая распределение ключей Threadid 51506.
ПРОВЕРКА НА ПРАКТИКЕ
Независимо от того, какую версию MySQL (Oracle, Percona, MariaDB) вы используете, ни одна из них не может сражаться с одним врагом, которого у них всех общего: архитектурой InnoDB.
КЛАСТЕРНЫЙ ИНДЕКС
Пожалуйста, имейте в виду, что к каждой записи threadid прикреплен первичный ключ. Это означает, что когда вы читаете из индекса, он должен выполнить поиск первичного ключа в ClusteredIndex (с внутренним именем gen_clust_index) . В ClusteredIndex каждая страница InnoDB содержит как данные, так и информацию индекса PRIMARY KEY. Смотрите мой пост Best of MyISAM и InnoDB для получения дополнительной информации.
ИЗБЫТОЧНЫЕ ИНДЕКСЫ
В таблице много беспорядка, потому что некоторые индексы имеют одинаковые ведущие столбцы. MySQL и InnoDB должны перемещаться между беспорядком индекса, чтобы добраться до нужных узлов BTREE. Вы должны уменьшить этот беспорядок, выполнив следующее:
Зачем урезать эти показатели?
threadid_2
а такжеthreadid_visible_dateline
начать с тех же трех столбцовthreadid_visible_dateline
не нужно postid, так как это первичный ключ, и он встроенБУФЕРНОЕ КЕШИНГ
InnoDB Buffer Pool кэширует данные и страницы индекса. MyISAM кэширует только индексные страницы.
Только в этой области MyISAM не тратит время на кеширование данных. Это потому, что он не предназначен для кэширования данных. InnoDB кэширует каждую страницу данных и страницу индекса (и свою бабушку), к которой она обращается. Если ваш буферный пул InnoDB слишком мал, вы можете кэшировать страницы, делать недействительными страницы и удалять страницы в одном запросе.
ТАБЛИЦА ПЛАНОВ
Вы можете сбрить немного места в ряду, учитывая
importthreadid
иimportpostid
. У вас есть как BIGINTs. Они занимают 16 байтов в ClusteredIndex на строку.Вы должны запустить это
Это будет рекомендовать, какие типы данных эти столбцы должны быть для данного набора данных.
ВЫВОД
MyISAM имеет гораздо меньше проблем, чем InnoDB, особенно в области кэширования.
Несмотря на то, что вы раскрыли объем ОЗУ (
32GB
) и версию MySQL (Server version: 10.0.12-MariaDB-1~trusty-wsrep-log mariadb.org binary distribution, wsrep_25.10.r4002
), в этой головоломке есть и другие части, которые вы не раскрылиmy.cnf
Если вы можете добавить эти вещи к вопросу, я могу уточнить.
ОБНОВЛЕНИЕ 2014-08-28 11:27 ПО ВОСТОЧНОМУ ВРЕМЕНИ
Вы должны увеличить потоки
Я хотел бы рассмотреть возможность отключения кэша запросов (см. Мой недавний пост, почему query_cache_type отключен по умолчанию, начиная с MySQL 5.6? )
Я бы сохранил буферный пул
Увеличьте потоки очистки (если вы используете DML для нескольких таблиц)
ДАЙТЕ ЭТО ПОПРОБУЙТЕ !!!
источник
@RolandMySQLDBA дал правильную подсказку, чтобы ответить на вопрос. Проблема, похоже, заключается в запросе, и для того, чтобы результаты были возвращены, каждое из этих полей должно быть прочитано (каким-то образом из базы данных).
Я удалил все индексы, кроме
PRIMARY KEY
, и вставил этот новый индекс:ALTER TABLE newbb_innopost ADD INDEX threadid_visible_dateline_index (threadid,visible,dateline,userid,attach,ipaddress);
Эта ссылка объясняет, что здесь происходит ( охватывающий индекс ): Запрашиваемые поля запроса, которые
postid,attach
теперь можно извлечь из самого ключа. Это сохраняет проверку реальных данных и использование ввода / вывода на жесткий диск.Все запросы теперь выполняются с 0,00 секунд .. :)
Большое спасибо всем за вашу помощь.
Изменить : фактическая основная проблема не решена, я просто обошел ее с помощью этой техники. InnoDB нуждается в серьезном исправлении в этой области.
источник
SQL_NO_CACHE
.Судя по вашим запросам и таблицам, кажется, что вы выбираете данные из таблицы временных рядов. Таким образом, может быть, что время запроса медленное, потому что вы вставляете одновременно?
Если эти две вещи верны, то могу ли я предложить рассмотреть ScaleDB в качестве альтернативы? Вы все еще будете на MariaDB, просто (возможно) более подходящий движок.
http://www.scaledb.com - домашняя страница http://www.scaledb.com/download-form.php - наш продукт
источник
Оба движка будут выполнять запрос намного быстрее с
Это потому, что это будет «покрывающий» индекс, и он будет работать практически так же (используя индекс BTree).
Также я скажу, что это невозможно для любого двигателя на «холодном» сервере:
Пожалуйста, используйте
SQL_NO_CACHE
каждый раз при запуске таймингов - мы не хотим, чтобы кеш запросов искажал выводы.Другой быстрый подход (вне зависимости от кэширования ввода / вывода):
Используйте InnoDB и измените с
PRIMARY KEY (postid)
наПричина в том, что это приведет к тому, что все соответствующие строки будут смежными, что потребует меньшего количества операций ввода-вывода и т. Д. Это
INDEX(postid)
должно оставатьсяAUTO_INCREMENT
счастливым. Предостережение: это портит все второстепенные ключи - некоторые будут быстрее, некоторые медленнее.источник
Хотя это не относится напрямую к @jollyroger, потому что он уже имеет правильные настройки, но я получил значительное улучшение, изменив
innodb_buffer_pool_size
до 70% своей оперативной памяти, как объяснено в разделе Почему myisam медленнее, чем InnodbСначала
MyISAM
было медленно, но хорошо. Затем всеInnoDB
стало плохо, как в 100 раз медленнее в этом вопросе, и после изменения настройкиInnoDB
стал в 10 раз быстрееMyISAM
.Моя настройка по умолчанию была на 8 МБ, что очень мало.
источник