新 MySQL 服务器比旧服务器慢
New MySQL Server slower than the old
总而言之,我有一台新的 mysql 服务器比它要替换的服务器慢 运行。我试图确定这是否是由于我正在测试它时新服务器上几乎不存在的负载(IE:查询优化器不知道这样做)。我只是不想打开这个东西的开关,然后我们的应用程序超时并死掉。
现在了解详情...两者都是 MySQL (Percona) 5.5 服务器。
"old" 服务器是 Xeon 8c/16t、128GB 内存、6x SAS 15k RAID10 机箱。
"new" 服务器是双 Xeon、16c/32t、256GB 内存、6 个 SSD RAID 10 盒。
旧服务器是 运行 debian,新服务器是 Ubuntu。
这几乎是两者之间唯一的非硬件差异。
两者都使用完全相同的 my.cnf 配置。
MySQL 数据库严格来说是 INNODB。
我将 "new" 服务器设置为 "old" 的从属服务器以进行测试。
然而,大多数 select 查询在新的、更快的硬件上执行时会慢 2-10 倍。即使在缓冲池有时间加载之后,后续查询运行仍然慢得多。尽管配置相同,但新服务器几乎不会缓存任何内容。
EXPLAIN 并不总是显示相同的执行计划。
如果我在新盒子上使用 FORCE INDEX 来获得正确的计划,这通常会有所帮助,但并非总是如此。
说到底,下面是每个盒子上当前 my.cnf 的调整部分。目前的在线服务器(旧)大约有 600 Selects/sec、150 InsertUpdates/sec。偶尔会增加到 ~2 倍的音量。
key_buffer = 128M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
max_connections = 350
read_rnd_buffer_size = 2M
read_buffer_size = 1M
sort_buffer_size = 2M
join_buffer_size = 3M
bulk_insert_buffer_size = 8M
table_open_cache = 4096
table_definition_cache = 2048
thread_cache_size = 32
max_heap_table_size = 64M
tmp_table_size = 64M
query_cache_limit = 4M
query_cache_size = 128M
default-storage-engine = innodb
innodb_buffer_pool_size = 81920M
innodb_additional_mem_pool_size = 20M
innodb_buffer_pool_instances = 4
innodb_log_file_size = 256M
innodb_log_buffer_size = 4M
innodb_thread_concurrency = 12
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit = 2
innodb_file_format = barracuda
innodb_support_xa = 0
innodb_file_per_table = true
innodb_max_dirty_pages_pct=75
innodb_read_io_threads = 8
innodb_write_io_threads = 8
innodb_io_capacity = 500
提前感谢您的帮助。
----编辑:示例查询和解释---
这是一个更糟糕的查询(故意选择的),它使用联合和连接。它正在查看两个表中的 RFID 数据并将其合并。
Log_RFID_WebService 有大约 500 万行。
Log_RFID_Zonal 有大约 200 万行。
旧服务器执行时间(3 次运行):.110、.074、.074
新服务器执行时间(3 次运行):.234、.250、.249
同样,似乎是某种缓存问题……或者新服务器上的临时表要慢得多……这对我来说仍然没有意义
SELECT
sql_calc_found_rows
Q.*,D.MktDlrCode,GetLastOrder(Q.CustId,D.StoreId,Q.Timestamp) As LastOrder
FROM
((SELECT
Zonal.ID,Zonal.CustId,Zonal.SID,'' As Lane,Zonal.RFIDtag,ANT.Antenna,ANT.Location,ANT.Direction,Timestamp,DATE_FORMAT(Timestamp,'%c/%d/%y %l:%i:%s %p') As DateTimestamp
FROM Portal.Log_RFID_Zonal As Zonal
INNER JOIN Portal.Log_RFID_Antennas As ANT ON
ANT.Antenna=Zonal.LocationCode AND
ANT.SID=Zonal.SID AND
ANT.IgnoreFlag=0
WHERE
Zonal.Timestamp>=STR_TO_DATE('08/01/2015','%m/%d/%Y') AND
Zonal.Timestamp<DATE_ADD(STR_TO_DATE('08/01/2015','%m/%d/%Y'), INTERVAL 1 day)
ORDER BY Zonal.Timestamp DESC
)
UNION
(SELECT
RFID.ID,RFID.CustId,RFID.SID,RFID.Lane,RFID.RFIDtag,ANT.Antenna,ANT.Location,ANT.Direction,Timestamp,DATE_FORMAT(Timestamp,'%c/%d/%y %l:%i:%s %p') As DateTimestamp
FROM Portal.Log_RFID_WebService As RFID
INNER JOIN Portal.Log_RFID_Antennas As ANT ON
ANT.Antenna=RFID.LocationCode AND
ANT.SID=RFID.SID AND
ANT.IgnoreFlag=0
WHERE
RFID.Timestamp>=STR_TO_DATE('08/01/2015','%m/%d/%Y') AND
RFID.Timestamp<DATE_ADD(STR_TO_DATE('08/01/2015','%m/%d/%Y'), INTERVAL 1 day)
ORDER BY RFID.Timestamp DESC
)
ORDER BY
Timestamp DESC
) As Q
INNER JOIN Stores As D ON
D.StoreId=Q.SID AND
D.ReportFlag=1
LIMIT 0,25;
对于此特定查询,两台服务器上的解释相同:
Id SelType Table Type Key Rows Extra
1 PRIMARY <derived> ALL 300 Using where;Using Index
1 PRIMARY D ref StoreId 1 Using Where
2 DERIVED Zonal range ix1 6368 Using where
2 DERIVED ANT eq_ref PRIMARY 1 Using where
3 UNION RFID range ix1 938 Using where
3 UNION ANT eq_ref PRIMARY 1 Using where
UNION RESULT ALL 0 Using filesort
奇怪的是,在新服务器上禁用超线程似乎可以解决问题。永远不会猜到这会在低负载情况下产生影响。
总而言之,我有一台新的 mysql 服务器比它要替换的服务器慢 运行。我试图确定这是否是由于我正在测试它时新服务器上几乎不存在的负载(IE:查询优化器不知道这样做)。我只是不想打开这个东西的开关,然后我们的应用程序超时并死掉。
现在了解详情...两者都是 MySQL (Percona) 5.5 服务器。 "old" 服务器是 Xeon 8c/16t、128GB 内存、6x SAS 15k RAID10 机箱。 "new" 服务器是双 Xeon、16c/32t、256GB 内存、6 个 SSD RAID 10 盒。
旧服务器是 运行 debian,新服务器是 Ubuntu。 这几乎是两者之间唯一的非硬件差异。 两者都使用完全相同的 my.cnf 配置。 MySQL 数据库严格来说是 INNODB。
我将 "new" 服务器设置为 "old" 的从属服务器以进行测试。 然而,大多数 select 查询在新的、更快的硬件上执行时会慢 2-10 倍。即使在缓冲池有时间加载之后,后续查询运行仍然慢得多。尽管配置相同,但新服务器几乎不会缓存任何内容。
EXPLAIN 并不总是显示相同的执行计划。 如果我在新盒子上使用 FORCE INDEX 来获得正确的计划,这通常会有所帮助,但并非总是如此。
说到底,下面是每个盒子上当前 my.cnf 的调整部分。目前的在线服务器(旧)大约有 600 Selects/sec、150 InsertUpdates/sec。偶尔会增加到 ~2 倍的音量。
key_buffer = 128M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
max_connections = 350
read_rnd_buffer_size = 2M
read_buffer_size = 1M
sort_buffer_size = 2M
join_buffer_size = 3M
bulk_insert_buffer_size = 8M
table_open_cache = 4096
table_definition_cache = 2048
thread_cache_size = 32
max_heap_table_size = 64M
tmp_table_size = 64M
query_cache_limit = 4M
query_cache_size = 128M
default-storage-engine = innodb
innodb_buffer_pool_size = 81920M
innodb_additional_mem_pool_size = 20M
innodb_buffer_pool_instances = 4
innodb_log_file_size = 256M
innodb_log_buffer_size = 4M
innodb_thread_concurrency = 12
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit = 2
innodb_file_format = barracuda
innodb_support_xa = 0
innodb_file_per_table = true
innodb_max_dirty_pages_pct=75
innodb_read_io_threads = 8
innodb_write_io_threads = 8
innodb_io_capacity = 500
提前感谢您的帮助。
----编辑:示例查询和解释---
这是一个更糟糕的查询(故意选择的),它使用联合和连接。它正在查看两个表中的 RFID 数据并将其合并。
Log_RFID_WebService 有大约 500 万行。 Log_RFID_Zonal 有大约 200 万行。
旧服务器执行时间(3 次运行):.110、.074、.074
新服务器执行时间(3 次运行):.234、.250、.249
同样,似乎是某种缓存问题……或者新服务器上的临时表要慢得多……这对我来说仍然没有意义
SELECT
sql_calc_found_rows
Q.*,D.MktDlrCode,GetLastOrder(Q.CustId,D.StoreId,Q.Timestamp) As LastOrder
FROM
((SELECT
Zonal.ID,Zonal.CustId,Zonal.SID,'' As Lane,Zonal.RFIDtag,ANT.Antenna,ANT.Location,ANT.Direction,Timestamp,DATE_FORMAT(Timestamp,'%c/%d/%y %l:%i:%s %p') As DateTimestamp
FROM Portal.Log_RFID_Zonal As Zonal
INNER JOIN Portal.Log_RFID_Antennas As ANT ON
ANT.Antenna=Zonal.LocationCode AND
ANT.SID=Zonal.SID AND
ANT.IgnoreFlag=0
WHERE
Zonal.Timestamp>=STR_TO_DATE('08/01/2015','%m/%d/%Y') AND
Zonal.Timestamp<DATE_ADD(STR_TO_DATE('08/01/2015','%m/%d/%Y'), INTERVAL 1 day)
ORDER BY Zonal.Timestamp DESC
)
UNION
(SELECT
RFID.ID,RFID.CustId,RFID.SID,RFID.Lane,RFID.RFIDtag,ANT.Antenna,ANT.Location,ANT.Direction,Timestamp,DATE_FORMAT(Timestamp,'%c/%d/%y %l:%i:%s %p') As DateTimestamp
FROM Portal.Log_RFID_WebService As RFID
INNER JOIN Portal.Log_RFID_Antennas As ANT ON
ANT.Antenna=RFID.LocationCode AND
ANT.SID=RFID.SID AND
ANT.IgnoreFlag=0
WHERE
RFID.Timestamp>=STR_TO_DATE('08/01/2015','%m/%d/%Y') AND
RFID.Timestamp<DATE_ADD(STR_TO_DATE('08/01/2015','%m/%d/%Y'), INTERVAL 1 day)
ORDER BY RFID.Timestamp DESC
)
ORDER BY
Timestamp DESC
) As Q
INNER JOIN Stores As D ON
D.StoreId=Q.SID AND
D.ReportFlag=1
LIMIT 0,25;
对于此特定查询,两台服务器上的解释相同:
Id SelType Table Type Key Rows Extra
1 PRIMARY <derived> ALL 300 Using where;Using Index
1 PRIMARY D ref StoreId 1 Using Where
2 DERIVED Zonal range ix1 6368 Using where
2 DERIVED ANT eq_ref PRIMARY 1 Using where
3 UNION RFID range ix1 938 Using where
3 UNION ANT eq_ref PRIMARY 1 Using where
UNION RESULT ALL 0 Using filesort
奇怪的是,在新服务器上禁用超线程似乎可以解决问题。永远不会猜到这会在低负载情况下产生影响。