如何使用当前服务器资源提高 MySQL 性能?

Xup*_* MV 7 mysql performance memory database-tuning

我有一个 MySQL 数据库,我的一些查询变得很慢。查询时间不稳定。大多数查询都很快,但其中一些(可能是读取和返回的数据较少)需要很长时间。

我知道最佳实践是添加索引或重构代码,但我已经添加了索引并且我不想重构代码(至少当我有其他变体时)。

我有 8 Gb 空闲内存,CPU 在峰值时仅加载到 25%。所以我想使用我所有的资源。

我尝试调整 MySQL 配置,但我没有这种调整的经验,所以我提高了生产力并没有我想要的那么多。下面是一个例子:

# Query_time: 3.019647  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 504
SET timestamp=1313380874;
SELECT COUNT(inboxentities.id) FROM inboxentities  WHERE (active=true)AND(deleted=false)AND((to_ = '44219ca4-a657-4909-b30d-a7ba0ed8e4b0'))AND(notification=true);
Run Code Online (Sandbox Code Playgroud)

PSinboxentities有 500.000 条记录。我有 index1 (idx_to) :to_和 index2 (idx_complex): deleted, notification, active,to_

这是解释选择的结果:

+----+-------------+---------------+------+------------------------------------------------+--------+---------+-------+------+-------------+
| id | select_type | table         | type | possible_keys                                  | key    | key_len | ref   | rows | Extra       |
+----+-------------+---------------+------+------------------------------------------------+--------+---------+-------+------+-------------+
|  1 | SIMPLE      | inboxentities | ref  | idx_status,idx_statusToname,idx_to,idx_complex | idx_to | 768     | const |  286 | Using where |
+----+-------------+---------------+------+------------------------------------------------+--------+---------+-------+------+-------------+
Run Code Online (Sandbox Code Playgroud)

Rol*_*DBA 6

这是慢日志中的原始查询

SELECT COUNT(inboxentities.id) FROM inboxentities
WHERE (active=true)
AND (deleted=false)
AND ((to_ = '44219ca4-a657-4909-b30d-a7ba0ed8e4b0'))
AND (notification=true);
Run Code Online (Sandbox Code Playgroud)

为这样的查询建立索引的最有效方法是生成一个索引,该索引涵盖尽可能多的 WHERE 子句中的字段。考虑到该概念生成的索引称为覆盖索引

查看 WHERE 子句

  • 'active' 为真或假(2 个值)。仅该字段的索引是不平衡的。
  • 'deleted' 为真或假(2 个值)。仅该字段的索引是不平衡的。
  • “通知”为真或假(2 个值)。仅该字段的索引是不平衡的。
  • 'to_' 是一个值得索引和缩小的值。

尽管您定义了 idx_complex,但查询中还有一个元素导致不使用 idx_complex 索引:COUNT(inboxentities.id)子句。

你正在数桌子上的东西。除了 to_ 之外,索引没有指向表的引用点。MySQL Query Optimizer 会选择 idx_to,最简单的索引。要强制 MySQL 查询优化器选择您想要的覆盖索引 (idx_complex),只需从索引而不是表中 COUNT。我的建议是稍微更改查询:

SELECT COUNT(to_) FROM inboxentities
WHERE (active=true)
AND (deleted=false)
AND ((to_ = '44219ca4-a657-4909-b30d-a7ba0ed8e4b0'))
AND (notification=true);
Run Code Online (Sandbox Code Playgroud)

试一试 !!!

更新 2011-08-15 15:16 EDT

通过更改 my.cnf 以满足存储引擎性能需求,一些人已经看到了从边际到显着的性能提升。

您需要设置 MyISAM Ke​​y Cache 和 InnoDB Buffer Pool。

这将为您的给定数据集推荐合适大小的 MyISAM 密钥缓存:

SELECT CONCAT(ROUND(KBS/POWER(1024,
IF(PowerOf1024<0,0,IF(PowerOf1024>3,0,PowerOf1024)))+0.4999),
SUBSTR(' KMG',IF(PowerOf1024<0,0,
IF(PowerOf1024>3,0,PowerOf1024))+1,1))
recommended_key_buffer_size FROM
(SELECT LEAST(POWER(2,32),KBS1) KBS
FROM (SELECT SUM(index_length) KBS1
FROM information_schema.tables
WHERE engine='MyISAM' AND
table_schema NOT IN ('information_schema','mysql')) AA ) A,
(SELECT 2 PowerOf1024) B;
Run Code Online (Sandbox Code Playgroud)

这将为您的给定数据集推荐合适大小的 InnoDB 缓冲池

SELECT CONCAT(ROUND(KBS/POWER(1024,
IF(PowerOf1024<0,0,IF(PowerOf1024>3,0,PowerOf1024)))+0.49999),
SUBSTR(' KMG',IF(PowerOf1024<0,0,
IF(PowerOf1024>3,0,PowerOf1024))+1,1)) recommended_innodb_buffer_pool_size
FROM (SELECT SUM(data_length+index_length) KBS FROM information_schema.tables
WHERE engine='InnoDB') A,
(SELECT 2 PowerOf1024) B;
Run Code Online (Sandbox Code Playgroud)

顺便提一句

  • (SELECT 0 PowerOf1024) 以字节为单位生成答案
  • (SELECT 1 PowerOf1024) 以 KB 为单位生成答案
  • (SELECT 2 PowerOf1024) 以 MB 为单位生成答案
  • (SELECT 3 PowerOf1024) 以 GB 为单位生成答案

如果您超出此范围,请给我发电子邮件。

完成这些设置后,请确保Recommended_key_buffer_size 和Recommended_innodb_buffer_pool_size 的总和不超过已安装RAM 的75%。

更新 2011-08-15 15:35 EDT

您可能希望在服务器上运行 mysqltuner.pl,让它告诉您如何调整数据库连接的内存使用量。管理每个数据库连接的内存使用情况的设置包括

这些通常乘以max_connections

您可以从 Linux 命令行获取 mysqltuner.pl 下载,如下所示:

wget mysqltuner.pl
Run Code Online (Sandbox Code Playgroud)

它的输出是这样的:

$ perl mysqltuner.pl

 >>  MySQLTuner 1.2.0 - Major Hayden <major@mhtx.net>
 >>  Bug reports, feature requests, and downloads at http://mysqltuner.com/
 >>  Run with '--help' for additional options and output filtering
Please enter your MySQL administrative login: username
Please enter your MySQL administrative password: (password hidden)

-------- General Statistics --------------------------------------------------
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.1.47-community-log
[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +Archive -BDB -Federated +InnoDB -ISAM -NDBCluster
[--] Data in MyISAM tables: 7G (Tables: 6)
[--] Data in InnoDB tables: 2G (Tables: 382)
[!!] Total fragmented tables: 84

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 12d 20h 24m 6s (54M q [49.462 qps], 555K conn, TX: 287B, RX: 95B)
[--] Reads / Writes: 62% / 38%
[--] Total buffers: 9.3G global + 48.2M per thread (1250 max threads)
[!!] Maximum possible memory usage: 68.2G (291% of installed RAM)
[OK] Slow queries: 0% (647/54M)
[OK] Highest usage of available connections: 5% (69/1250)
[OK] Key buffer size / total MyISAM indexes: 256.0M/19.4M
[OK] Key buffer hit rate: 100.0% (51M cached / 10 reads)
[OK] Query cache efficiency: 89.3% (47M cached / 52M selects)
[!!] Query cache prunes per day: 60670
[OK] Sorts requiring temporary tables: 0% (239 temp sorts / 1M sorts)
[!!] Temporary tables created on disk: 47% (1M on disk / 2M total)
[OK] Thread cache hit rate: 99% (103 created / 555K connections)
[OK] Table cache hit rate: 21% (722 open / 3K opened)
[OK] Open file limit used: 0% (70/32K)
[OK] Table locks acquired immediately: 99% (12M immediate / 12M locks)
[OK] InnoDB data size / buffer pool: 2.4G/8.0G

-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    Reduce your overall MySQL memory footprint for system stability
    Increasing the query_cache size over 128M may reduce performance
    When making adjustments, make tmp_table_size/max_heap_table_size equal
    Reduce your SELECT DISTINCT queries without LIMIT clauses
Variables to adjust:
  *** MySQL's maximum memory usage is dangerously high ***
  *** Add RAM before increasing MySQL buffer variables ***
    query_cache_size (> 1G) [see warning above]
    tmp_table_size (> 32M)
    max_heap_table_size (> 32M)
Run Code Online (Sandbox Code Playgroud)