Percona 5.7 在许多连接上都很慢
Posted
技术标签:
【中文标题】Percona 5.7 在许多连接上都很慢【英文标题】:Percona 5.7 Slow on many Joins 【发布时间】:2017-02-08 19:13:03 【问题描述】:我们最近将 percona 5.5 sql 服务器升级到 percona 5.7。到目前为止效果很好。不幸的是,我们有一个巨大的查询,在 5.7 下非常慢。低于 5.5。即使使用 sql_no_cache,它也只需要不到一秒钟的时间。使用 Percona 5.7。执行此查询最多需要 1 分钟。奇怪的是,随着我们使用的组合指标越多,它变得越慢。删除所有组合索引会导致执行时间为 30 秒。强制 sql_straight_join 使查询在不到一秒的时间内运行。
所以这里是查询:
SELECT t0_.tree_id AS tree_id0, t1_.treetype_name AS treetype_name1, c2_.contentelement_id AS contentelement_id2, t0_.tree_name AS tree_name3, (CASE WHEN t3_.treetype_name <> 'global' THEN t4_.tree_name ELSE t0_.tree_name END) AS sclr4, p5_.picture_id AS picture_id5, t6_.tree_misc_value_text AS tree_misc_value_text6, (CASE WHEN t3_.treetype_name <> 'global' THEN t7_.tree_misc_value_text ELSE t6_.tree_misc_value_text END) AS sclr7, w8_.widgetgeneral_slug AS widgetgeneral_slug8, (CASE WHEN t3_.treetype_name <> 'global' THEN w9_.widgetgeneral_slug ELSE w8_.widgetgeneral_slug END) AS sclr9, t10_.tree_misc_value_text AS tree_misc_value_text10, t11_.tree_misc_value_text AS tree_misc_value_text11
FROM tree_relation t12_
INNER JOIN tree t4_ ON t12_.tree_relation_parent = t4_.tree_id
INNER JOIN treetype t3_ ON t4_.tree_type_id = t3_.treetype_id AND (t3_.treetype_name IN ('global', 'country'))
INNER JOIN contentelement c13_ ON t4_.tree_id = c13_.contentelement_tree_id
INNER JOIN contentleaf c14_ ON c13_.contentelement_contentleaf_id = c14_.contentleaf_id AND (c14_.contentleaf_contentbranch_id = 1)
INNER JOIN widgetgeneral w9_
INNER JOIN widgetabstract w15_ ON w9_.widgetabstract_id = w15_.widgetabstract_id AND (w15_.widgetabstract_contentelement_id = c13_.contentelement_id AND w15_.widgetabstract_discriminator IN ('general') AND w15_.widgetabstract_state = 'preview')
INNER JOIN tree t0_ ON t12_.tree_relation_child = t0_.tree_id
INNER JOIN treetype t1_ ON t0_.tree_type_id = t1_.treetype_id AND (t1_.treetype_name IN ('city','region'))
INNER JOIN contentelement c2_ ON t0_.tree_id = c2_.contentelement_tree_id
INNER JOIN contentleaf c16_ ON c2_.contentelement_contentleaf_id = c16_.contentleaf_id AND (c16_.contentleaf_contentbranch_id = 1)
INNER JOIN widgetgeneral w8_
INNER JOIN widgetabstract w17_ ON w8_.widgetabstract_id = w17_.widgetabstract_id AND (w17_.widgetabstract_contentelement_id = c2_.contentelement_id AND w17_.widgetabstract_discriminator IN ('general') AND w17_.widgetabstract_state = 'preview')
INNER JOIN widgetgeneral w18_
INNER JOIN widgetabstract w19_ ON w18_.widgetabstract_id = w19_.widgetabstract_id AND (w19_.widgetabstract_contentleaf_id = c16_.contentleaf_id AND w19_.widgetabstract_discriminator IN ('general') AND w19_.widgetabstract_state = 'preview')
LEFT JOIN picture p5_ ON t0_.tree_picture_id = p5_.picture_id
LEFT JOIN tree_misc t6_ ON t0_.tree_id = t6_.tree_misc_tree_id AND (t6_.tree_misc_attributetype_key = 'flagId')
LEFT JOIN tree_misc t7_ ON t4_.tree_id = t7_.tree_misc_tree_id AND (t7_.tree_misc_attributetype_key = 'flagId')
LEFT JOIN tree_misc t10_ ON t0_.tree_id = t10_.tree_misc_tree_id AND (t10_.tree_misc_attributetype_key = 'latitude')
LEFT JOIN tree_misc t11_ ON t0_.tree_id = t11_.tree_misc_tree_id AND (t11_.tree_misc_attributetype_key = 'longitude')
WHERE w17_.widgetabstract_visibility = 'active' OR (w17_.widgetabstract_visibility = 'parent' AND w19_.widgetabstract_visibility = 'active')
以及 5.7 的解释:
我们尝试了升级以及完全空白安装。打开和关闭所有 sql 模式和查询优化器选项。如果您需要更多信息或服务器变量,请告诉我。
操作系统:Debian GNU/Linux 8 (jessie) 服务器版本为:5.7.14-7-log Percona Server (GPL),Release '7',Revision '083e298'
也许你知道我们缺少什么。
编辑: 添加配置
[mysqld]
port = 3306
user = mysql
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
max_connect_errors = 1000000
log-error = /var/log/mysql/error.log
skip-external-locking
myisam-recover-options = BACKUP
character-set-server = utf8
collation-server = utf8_general_ci
interactive_timeout = 28800
wait_timeout = 28800
skip-name-resolve
group_concat_max_len = 268435456
innodb_file_per_table
innodb_buffer_pool_size = 48G
innodb_buffer_pool_instances = 1
innodb_flush_log_at_trx_commit = 1
innodb_data_file_path = ibdata1:2G:autoextend
innodb_log_file_size = 256M
innodb_log_buffer_size = 64M
innodb_file_format = barracuda
innodb_flush_method = O_DIRECT[mysqld_safe]
syslog
numa_interleave
# Per Thread
sort_buffer_size = 4M
read_buffer_size = 2M
# Cache/connection relevant
thread_cache_size = 850
table_open_cache = 4048
max_connections = 1300
# MyISAM settings (also valid for queries with temporary tables)
key_buffer_size = 128M
myisam_sort_buffer_size = 16M
# Misc
max_allowed_packet = 256M
max_heap_table_size = 16M
thread_stack = 192K
tmp_table_size = 16M
# Query cache
query_cache_limit = 5M
query_cache_size = 4024M
server-id = 102
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = mixed
expire_logs_days = 10
max_binlog_size = 100M
# enforce syncing of every transation to binlog (crash safe, with bbu this should be fast)
sync_binlog = 1
sync_relay_log = 1
sync_master_info = 1
sync_relay_log_info = 1
relay-log = mysqld-relay-bin
skip-slave-start
log-slave-updates
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1
log-queries-not-using-indexes
编辑 2: 为 5.5 添加解释
【问题讨论】:
MySQL 配置文件会很好,尤其是innodb_buffer_pool_size
的值。添加索引不会像那样使查询工作得更快..
添加配置 @Mjh - innodb_buffer_pool_size 为 48G,但也尝试了完整的空白配置
你有 5.5 EXPLAIN
吗?这可能更容易看出优化出了什么问题。
64GB 内存?...
您有任何“复合”索引吗?我特别关注w15_
。
【参考方案1】:
新的连接排序可能是由于 MySQL 5.7 高估了基于 WHERE 和 ON 子句的过滤效果。在 MySQL 5.6 中,没有考虑过滤,这通常会导致选择不必要的昂贵连接排序。一般来说,MySQL 5.7 通过考虑过滤通常能够找到更好的连接排序。但是,对于未索引列上的条件,过滤估计只是一种猜测,可能不适用于选择性不高的条件。
您可以通过设置 optimizer_switch='condition_fanout_filter=off' 来恢复到 5.6 的行为,或者您可以使用 STRAIGHT_JOIN 来强制执行特定的联接排序。
【讨论】:
感谢您的回答。我们已经尝试过“condition_fanout_filter=off”,但它对查询运行时没有显着影响。 嗯。然后我想我需要查看优化器跟踪以了解发生了什么。以上是关于Percona 5.7 在许多连接上都很慢的主要内容,如果未能解决你的问题,请参考以下文章
在aliyun主机上通过yum方式安装Percona版MYSQL 5.7