为什么InnoDB 100x上的简单SELECT速度比MyISAM慢?


33

我有一个很烦人的问题。我想使用INNODB作为我的主要数据库引擎,而放弃MyISAM,因为我需要前者使用galera-cluster来实现冗余。

我将newbb_post表复制(描述如下)到一个名为的新表中,newbb_innopost并将其更改为InnoDB。这些表当前5,390,146每个都有条目。

在新启动的数据库上运行这些选择(因此此时不涉及缓存!),该数据库会产生以下结果(省略完整的输出,请注意,我什至不要求数据库对结果进行排序):

从newbb_post中选择post.postid,post.attach作为post,而post.threadid = 51506;

。
。
| 5401593 | 0 |
| 5401634 | 0 |
+ --------- + -------- +
设置62510行(0.13秒)
从newbb_innopost中选择post.postid,post.attach作为post,而post.threadid = 51506;
。
。
| 5397410 | 0 |
| 5397883 | 0 |
+ --------- + -------- +
设置62510行(1分22.19秒)

0.13秒至86.19秒(!)

我想知道为什么会这样。我确实在这里阅读了有关InnoDB的Stackexchange的一些答案,并且有人建议将innodb_buffer_pool大小增加到已安装RAM的80%。这不会解决问题,对特定ID的初始查询将至少花费50倍以上的时间,并使整个Web服务器停滞不前,从而对数据库进行连接和查询。之后可能会启动缓存/缓冲区,但是此数据库中有超过100.000个线程,因此很有可能缓存将永远无法容纳要服务的所有相关查询。

上面的查询很简单(没有连接),并且使用了所有键:

从newbb_innopost解释选择post.postid,post.attach作为post在哪里post.threadid = 51506;
+ ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- +
| id | select_type | 桌子| 类型 可能的钥匙| 关键 key_len | 参考| 行| 额外|
+ ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- +
| 1 | 简单 发布| 参考| threadid,threadid_2,threadid_visible_dateline | threadid | 4 | const | 120144 | |
+ ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- +

这是MyISAM表:

创建表`newbb_post`(
  `postid` int(10)unsigned NOT NULL AUTO_INCREMENT,
  `threadid` int(10)unsigned NOT NULL默认值为'0',
  `parentid` int(10)unsigned 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默认值'0',
  `pagetext`中文字,
  `allowsmilie` smallint(6)NOT NULL缺省'0',
  `showsignature`smallint(6)NOT NULL默认为'0',
  ipaddress varchar(15)非空默认值'',
  `iconid` smallint(5)unsigned NOT NULL默认值为'0',
  `visible` smallint(6)NOT NULL缺省'0',
  `attach`smallint(5)unsigned NOT NULL缺省'0',
  `infraction` smallint(5)unsigned NOT NULL DEFAULT'0',
  `reportthreadid` int(10)unsigned NOT NULL缺省'0',
  `importthreadid` bigint(20)NOT NULL缺省'0',
  `importpostid` bigint(20)NOT NULL缺省'0',
  `converted_2_utf8` int(11)NOT NULL,
  htmlstate` enum('off','on','on_nl2br')NOT NULL默认'on_nl2br',
  主键(`postid`),
  KEY`threadid`(`threadid`,`userid`),
  KEY`importpost_index`(`importpostid`),
  KEY`dateline`(`dateline`),
  KEY`threadid_2`(`threadid`,`visible`,`dateline`),
  KEY`converted_2_utf8`(`converted_2_utf8`),
  KEY`threadid_visible_dateline`(`threadid`,`visible`,`dateline`,`userid`,`postid`),
  KEY`ipaddress`(`ipaddress`),
  KEY`userid`(`userid`,`parentid`),
  KEY`user_date`(`userid`,`dateline`)
)ENGINE = MyISAM AUTO_INCREMENT = 5402802 DEFAULT CHARSET = latin1

这是InnoDB表(完全相同):

创建表`newbb_innopost`(
  `postid` int(10)unsigned NOT NULL AUTO_INCREMENT,
  `threadid` int(10)unsigned NOT NULL默认值为'0',
  `parentid` int(10)unsigned 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默认值'0',
  `pagetext`中文字,
  `allowsmilie` smallint(6)NOT NULL缺省'0',
  `showsignature`smallint(6)NOT NULL默认为'0',
  ipaddress varchar(15)非空默认值'',
  `iconid` smallint(5)unsigned NOT NULL默认值为'0',
  `visible` smallint(6)NOT NULL缺省'0',
  `attach`smallint(5)unsigned NOT NULL缺省'0',
  `infraction` smallint(5)unsigned NOT NULL DEFAULT'0',
  `reportthreadid` int(10)unsigned NOT NULL缺省'0',
  `importthreadid` bigint(20)NOT NULL缺省'0',
  `importpostid` bigint(20)NOT NULL缺省'0',
  `converted_2_utf8` int(11)NOT NULL,
  htmlstate` enum('off','on','on_nl2br')NOT NULL默认'on_nl2br',
  主键(`postid`),
  KEY`threadid`(`threadid`,`userid`),
  KEY`importpost_index`(`importpostid`),
  KEY`dateline`(`dateline`),
  KEY`threadid_2`(`threadid`,`visible`,`dateline`),
  KEY`converted_2_utf8`(`converted_2_utf8`),
  KEY`threadid_visible_dateline`(`threadid`,`visible`,`dateline`,`userid`,`postid`),
  KEY`ipaddress`(`ipaddress`),
  KEY`userid`(`userid`,`parentid`),
  KEY`user_date`(`userid`,`dateline`)
)ENGINE = InnoDB AUTO_INCREMENT = 5402802 DEFAULT CHARSET = latin1

服务器,具有32GB RAM:

服务器版本:10.0.12-MariaDB-1〜trusty-wsrep-log mariadb.org二进制分发版,wsrep_25.10.r4002

如果您需要所有innodb_变量设置,我可以将其附加到这篇文章。

更新:

我将所有索引与主索引分开,之后的结果如下所示:

。
。
| 5402697 | 0 |
| 5402759 | 0 |
+ --------- + -------- +
设置62510行(29.74秒)
从newbb_innopost解释选择post.postid,post.attach作为post在哪里post.threadid = 51506;
+ ------ + ------------- + ------- + ------ + ------------- -+ ------ + --------- + ------ + --------- + ------------- +
| id | select_type | 桌子| 类型 可能的钥匙| 关键 key_len | 参考| 行| 额外|
+ ------ + ------------- + ------- + ------ + ------------- -+ ------ + --------- + ------ + --------- + ------------- +
| 1 | 简单 发布| 全部| NULL | NULL | NULL | NULL | 5909836 | 在哪里使用
+ ------ + ------------- + ------- + ------ + ------------- -+ ------ + --------- + ------ + --------- + ------------- +
设置1行(0.00秒)

在此之后,我将一个索引重新添加到混合中,即threadid,结果如下:

。
。
| 5402697 | 0 |
| 5402759 | 0 |
+ --------- + -------- +
设置62510行(11.58秒)
从newbb_innopost解释选择post.postid,post.attach作为post在哪里post.threadid = 51506;
+ ------ + ------------- + ------- + ------ + ------------- -+ ---------- + --------- + ------- + -------- + ------- +
| id | select_type | 桌子| 类型 可能的钥匙| 关键 key_len | 参考| 行| 额外|
+ ------ + ------------- + ------- + ------ + ------------- -+ ---------- + --------- + ------- + -------- + ------- +
| 1 | 简单 发布| 参考| threadid | threadid | 4 | const | 124622 | |
+ ------ + ------------- + ------- + ------ + ------------- -+ ---------- + --------- + ------- + -------- + ------- +
设置1行(0.00秒)

奇怪的是,没有任何相关索引,完整扫描仅花费29秒,而使用索引(!)则为88秒。

仅通过一个完美定制的索引,它仍然需要11秒才能完成-对于任何实际使用而言,仍然太慢了。

更新2:

我在另一台服务器上以完全相同的硬件配置和完全相同的数据库/表设置了MySQL(5.5.38-0ubuntu0.14.04.1(Ubuntu))。

结果几乎相同,首先是MyISAM表:

。
。
| 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
套接字= /var/run/mysqld/mysqld.sock

#这是一些特定程序的条目
#以下值假设您的RAM至少为32M

#这被正式称为[safe_mysqld]。这两个版本当前都已解析。
[mysqld_safe]
套接字= /var/run/mysqld/mysqld.sock
好= 0

[mysqld]
#
# * 基本设置
#
用户= MySQL
pid文件= /var/run/mysqld/mysqld.pid
套接字= /var/run/mysqld/mysqld.sock
端口= 3306
basedir = / usr
datadir = / var / lib / mysql
tmpdir = / tmp
lc_messages_dir = / usr / share / mysql
lc_messages = zh_CN
跳过外部锁定
#
#现在默认不监听网络,而不是跳过网络
#本地主机,兼容性更高,安全性也更高。
绑定地址= 127.0.0.1
#
# * 微调
#
max_connections = 100
connect_timeout = 5
wait_timeout = 600
max_allowed_pa​​cket = 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 =备份
key_buffer_size = 128M
#open-files-limit = 2000
table_open_cache = 400
myisam_sort_buffer_size = 512M
parallel_insert = 2
read_buffer_size = 2M
read_rnd_buffer_size = 1M
#
#*查询缓存配置
#
#仅缓存微小的结果集,因此我们可以在查询缓存中容纳更多结果集。
query_cache_limit = 128K
query_cache_size = 64M
#用于更密集的写入设置,设置为DEMAND或OFF
#query_cache_type =需求
#
#*记录和复制
#
#两个位置都被cronjob旋转。
#请注意,此日志类型是性能杀手。
#从5.1开始,您可以在运行时启用日志!
#general_log_file = /var/log/mysql/mysql.log
#general_log = 1
#
#由于/etc/mysql/conf.d/mysqld_safe_syslog.cnf,错误日志记录进入syslog。
#
#我们确实想了解网络错误等
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-queries-not-using-indexes
#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
#只读
#
#如果应用程序支持它,则此更严格的sql_mode可以防止某些
#错误,例如插入无效的日期等。
#sql_mode = NO_ENGINE_SUBSTITUTION,传统
#
#* InnoDB
#
#InnoDB默认情况下在/ var / lib / mysql /中具有10MB数据文件启用。
#阅读手册,了解更多与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 GUI“ tinyca”。
#
#ssl-ca = / etc / mysql / cacert.pem
#ssl-cert = / etc / mysql / server-cert.pem
#ssl-key = / etc / mysql / server-key.pem



[mysqldump]
快
引用名称
max_allowed_pa​​cket = 16M

[mysql]
#no-auto-rehash#更快地启动mysql,但没有制表符完成

[isamchk]
key_buffer = 16M

#
#*重要:其他设置可以覆盖此文件中的设置!
#文件必须以'.cnf'结尾,否则将被忽略。
#
!includedir /etc/mysql/conf.d/

以及inno变量的内容:

MariaDB [(无)]>显示变量,例如'inno%';
+ ------------------------------------------- + ----- ------------------- +
| 变量名| 价值|
+ ------------------------------------------- + ----- ------------------- +
| innodb_adaptive_flushing | 开|
| innodb_adaptive_flushing_lwm | 10 |
| innodb_adaptive_hash_index | 开|
| 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 |
| innodb_checksums | 开|
| 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:autoextend |
| innodb_data_home_dir | |
| innodb_disable_sort_file_cache | 关闭|
| innodb_doublewrite | 开|
| innodb_empty_free_list_algorithm | 退让|
| innodb_fake_changes | 关闭|
| innodb_fast_shutdown | 1 |
| innodb_file_format | 羚羊|
| innodb_file_format_check | 开|
| innodb_file_format_max | 羚羊|
| innodb_file_per_table | 开|
| 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 | 开|
| 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 | 开|
| 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 |
| innodb_log_compressed_pa​​ges | 开|
| 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_pa​​ges | 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 | 开|
| innodb_stats_method | nulls_equal |
| innodb_stats_on_metadata | 关闭|
| innodb_stats_persistent | 开|
| 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 | 开|
| innodb_sync_array_size | 1 |
| innodb_sync_spin_loops | 30 |
| innodb_table_locks | 开|
| innodb_thread_concurrency | 0 |
| innodb_thread_sleep_delay | 10000 |
| innodb_track_changed_pa​​ges | 关闭|
| 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 | 开|
| innodb_use_native_aio | 开|
| innodb_use_stacktrace | 关闭|
| innodb_use_sys_malloc | 开|
| 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-20s。我确实要指出,对我而言(这是公告板的主表),至关重要的是,有关线程ID的第一个查询在不到一秒钟的时间内返回,因为有超过60.000线程并且Google-bot不断爬行这些线程。


评论不作进一步讨论;此对话已转移至聊天
保罗·怀特说GoFundMonica

Answers:


24

您的查询

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

乍一看,该查询应仅触及表的1.1597%(5390146中的62510)。给定线程ID 51506的密钥分发,应该很快。

现实检查

无论使用哪种版本的MySQL(Oracle,Percona,MariaDB),它们都无法与他们共同拥有的一个敌人作战:InnoDB体系结构。

InnoDB架构

聚集索引

请记住,每个threadid条目都附加了一个主键。这意味着,当您从索引中读取内容时,它必须在 ClusteredIndex(内部命名为gen_clust_index)。在ClusteredIndex中,每个InnoDB页面都包含数据和PRIMARY KEY索引信息。有关更多信息,请参阅我的MyISAM和InnoDB最佳文章。

冗余索引

由于某些索引具有相同的前导列,因此表中有很多混乱的地方。MySQL和InnoDB必须在索引混乱中导航才能到达所需的BTREE节点。您应该通过运行以下命令来减少混乱:

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`)
;

为什么要删除这些索引?

  • 前三个索引以threadid开头
  • threadid_2threadid_visible_dateline从相同的三列开始
  • threadid_visible_dateline 不需要postid,因为它是PRIMARY KEY并且已嵌入

缓冲训练

InnoDB缓冲池缓存数据和索引页。MyISAM仅缓存索引页。

仅在此区域,MyISAM不会浪费时间缓存数据。那是因为它不是设计用来缓存数据的。InnoDB缓存它接触的每个数据页和索引页(及其祖母)。如果您的InnoDB缓冲池太小,则可能在一个查询中缓存页面,使页面无效和删除页面。

桌面布局

您可以考虑importthreadid和,以减少行中的一些空间importpostid。您将它们作为BIGINT。它们在每行的ClusteredIndex中占用16个字节。

你应该运行这个

SELECT importthreadid,importpostid FROM newbb_innopost PROCEDURE ANALYSE();

这将建议这些列应是给定数据集的数据类型。

结论

与InnoDB相比,MyISAM所面临的挑战要少得多,尤其是在缓存方面。

虽然您揭示了RAM(32GB)的数量和MySQL(Server version: 10.0.12-MariaDB-1~trusty-wsrep-log mariadb.org binary distribution, wsrep_25.10.r4002)的版本,但是您还没有发现这个难题的其他内容

  • InnoDB设置
  • 核心数
  • 来自的其他设置 my.cnf

如果您可以将这些内容添加到问题中,我可以进一步阐述。

更新2014-08-28 11:27 EDT

您应该增加线程

innodb_read_io_threads = 64
innodb_write_io_threads = 16
innodb_log_buffer_size = 256M

我会考虑禁用查询缓存(请参阅我最近的帖子,为什么默认情况下从MySQL 5.6开始禁用query_cache_type?

query_cache_size = 0

我会保留缓冲池

innodb_buffer_pool_dump_at_shutdown=1
innodb_buffer_pool_load_at_startup=1

增加清除线程(如果您在多个表上执行DML)

innodb_purge_threads = 4

试试看 !!!


我知道在纯速度测试中InnoDB的速度会变慢,但是达到这个程度呢?我读过MySQL团队一直在努力缩小这一差距。我们仍在处理〜100倍的增长!问题-您是说使用“直接”非聚集B树索引(即不包括PK数据)更好地解决这种性质的查询吗?如果是这样,为什么/尚未实施?OP所需的功能绝对不是边际用例。
Vérace

您可以添加指向该图片的完整尺寸版本的链接吗?有些部分很难读:-)

@RolandMySQLDBA感谢您提供信息-我希望您不建议对InnoDB来说100倍的减速是“正常的” ...我可以忍受2倍或3倍,但100倍实在太多了。根据要求,我已将缺少的信息添加到我的问题中:)感谢您到目前为止的解释!本机的内核数量为8
jollyroger


1
非常感谢@RolandoMySQLDBA的帮助,不幸的是,即使是那些最后的调整也无济于事,InnoDB大约需要11-20秒才能完成。我根据您的答案尝试了一些方法-删除所有索引,并创建覆盖索引。这很有帮助。没有您对索引的解释,我将找不到此解决方案。要检查您的答案并自己写一个答案来解释我的所作所为:)
jollyroger 2014年

7

@RolandMySQLDBA提供了正确的提示来回答这个问题。问题似乎出在查询中,并且要返回结果,必须读取每个字段(以某种方式从数据库中读取)。

我删除了除以外的所有索引PRIMARY KEY,并插入了这个新索引:

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

这个 链接说明了这里发生的情况(涵盖index):postid,attach现在可以从键本身中提取查询的查询字段。这样可以节省检查真实数据和对硬盘使用I / O的麻烦。

现在所有查询的运行时间为0.00秒。.:)

非常感谢您的帮助。

编辑:实际的根本问题没有解决,我只是用这种技术规避了它。InnoDB在这方面需要认真解决。


我面临着同样的问题。myisma查询需要0.01秒,而innodb需要60秒,请尝试您的建议。
AMB 2015年

@AMB-0.01s闻起来像查询缓存;用SQL_NO_CACHE
里克·詹姆斯


0

两款发动机将运行查询更快

INDEX(threadid, attach, postid)

这是因为它将是一个“覆盖”索引,并且实际上将以相同的方式运行(使用索引BTree)。

另外,我将说这对于“冷”服务器上的任何一个引擎都是不可能的:

62510 rows in set (0.13 sec)

请用 SQL_NO_CACHE在运行计时时使用-我们不希望查询缓存污染结论。

另一种快速方法(不考虑I / O缓存):

使用InnoDB,并从更改PRIMARY KEY (postid)

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

其原因是,这将导致所有的相关行是相邻的,从而需要更少的I / O等的INDEX(postid)就是保持AUTO_INCREMENT快乐。警告:这会弄乱所有辅助键-有些会更快,有些会更慢。


0

尽管不适用于@jollyroger,因为他已经有了正确的设置,但是我将其innodb_buffer_pool_sizeRAM 更改为70%有了很大的改进,如为什么myisam慢于Innodb中所述

起初MyISAM很慢,但是还不错。然后InnoDB使情况变糟,类似于此问题中的慢100倍,更改设置后,InnoDB速度快10倍MyISAM

我的默认设置是8MB,远远不够。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.