【发布时间】:2018-10-10 17:58:43
【问题描述】:
我在服务器上有 2 个主表,具有相同的结构和数据(唯一的区别在于表的名称)。
表 #1:2.14 亿行,大小 40GB(25GB 索引)
表 #2:2600 万行,大小 5.5GB(3.5GB 索引)
第一个问题。当内存中有缓存时,一切都运行得非常快。如果我清理缓存或重新启动服务器,则 mysql 查询非常慢。 Debian 8 杰西。 MySQL总是将索引存储在内存中并将其作为缓存吗?因为经过一些操作,选择查询非常快。需要进行哪些操作才能使服务器正常运行:
如果我使用表 #1 的副本,那么据我所知,在其执行期间,会发生读取操作,同时信息被缓存到内存中。这是启动重复表时的free -m屏幕。
root@ns344370:~# free -m
total used free shared buffers cached
Mem: 128965 76802 52163 31 61 21714
-/+ buffers/cache: 55026 73939
Swap: 56141 0 56141
创建重复表时的结果:
root@ns344370:~# free -m
total used free shared buffers cached
Mem: 128965 126414 2551 31 49 65426
-/+ buffers/cache: 60938 68027
Swap: 56141 0 56141
缓存下有 50GB 的 RAM。重复表前105秒执行查询:
# Query_time: 105.469931 Lock_time: 0.000180 Rows_sent: 41041 Rows_examined: 2097994
SET timestamp=1539135133;
SELECT SQL_CACHE `id`, `currency`, `handLimit`, `date`, `pp1` AS `profit`,`psd1` AS `isSD` FROM `ps_hands` WHERE `p1` = '274606' AND (`date` >= '2018-10-01' AND `date` <= '2018-10-10')
UNION ALL (SELECT `id`, `currency`, `handLimit`, `date`, `pp2` AS `profit`, `psd2` AS `isSD` FROM `ps_hands` WHERE `p2` = '274606' AND (`date` >= '2018-10-01' AND `date` <= '2018-10-10'))
UNION ALL (SELECT `id`, `currency`, `handLimit`, `date`, `pp3` AS `profit`, `psd3` AS `isSD` FROM `ps_hands` WHERE `p3` = '274606' AND (`date` >= '2018-10-01' AND `date` <= '2018-10-10'))
UNION ALL (SELECT `id`, `currency`, `handLimit`, `date`, `pp4` AS `profit`, `psd4` AS `isSD` FROM `ps_hands` WHERE `p4` = '274606' AND (`date` >= '2018-10-01' AND `date` <= '2018-10-10'))
UNION ALL (SELECT `id`, `currency`, `handLimit`, `date`, `pp5` AS `profit`, `psd5` AS `isSD` FROM `ps_hands` WHERE `p5` = '274606' AND (`date` >= '2018-10-01' AND `date` <= '2018-10-10'))
UNION ALL (SELECT `id`, `currency`, `handLimit`, `date`, `pp6` AS `profit`, `psd6` AS `isSD` FROM `ps_hands` WHERE `p6` = '274606' AND (`date` >= '2018-10-01' AND `date` <= '2018-10-10'))
UNION ALL (SELECT `id`, `currency`, `handLimit`, `date`, `pp7` AS `profit`, `psd7` AS `isSD` FROM `ps_hands` WHERE `p7` = '274606' AND (`date` >= '2018-10-01' AND `date` <= '2018-10-10'))
UNION ALL (SELECT `id`, `currency`, `handLimit`, `date`, `pp8` AS `profit`, `psd8` AS `isSD` FROM `ps_hands` WHERE `p8` = '274606' AND (`date` >= '2018-10-01' AND `date` <= '2018-10-10'))
UNION ALL (SELECT `id`, `currency`, `handLimit`, `date`, `pp9` AS `profit`, `psd9` AS `isSD` FROM `ps_hands` WHERE `p9` = '274606' AND (`date` >= '2018-10-01' AND `date` <= '2018-10-10'))
ORDER BY `id` ASC;
在重复表之后是 0.2 秒而不是 105 秒。我正在考虑将磁盘从 SSHD 更改为 NVMe M2(快 5 倍)。但是我将有另外 4-5 个 50GB 的表,在这种情况下,我只是没有足够的 RAM。怎样成为? 我有 128GB 内存。除了这个项目,还有一个项目。在其上分配了 50GB。其余的用于这个项目和 MySQL。 我使用 MyISAM 而不是 InnoDB,因为在站点上只选择和插入操作。 InnoDB 慢了 20 倍,在家用机器上也检查过,使用 M.2 磁盘....这里是 mysql 配置文件:
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0
[mysqld]
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
query_cache_type = DEMAND
key_buffer_size = 55G
sort_buffer_size = 512M
read_buffer_size = 128M
max_allowed_packet = 32M
thread_stack = 192K
thread_cache_size = 4096
#MySQL Tuner
max_heap_table_size = 128M
tmp_table_size = 128M
table_open_cache = 4096
myisam-recover = BACKUP
max_connections = 2000
table_cache = 2048
thread_concurrency = 17
query_cache_limit = 128M
query_cache_size = 256M
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 1
#log-queries-not-using-indexes
expire_logs_days = 10
max_binlog_size = 100M
#binlog_do_db = include_database_name
#binlog_ignore_db = include_database_name
innodb_buffer_pool_size = 512M
[mysqldump]
quick
quote-names
max_allowed_packet = 16M
[mysql]
#no-auto-rehash # faster start of mysql but no tab completition
[isamchk]
key_buffer = 256M
!includedir /etc/mysql/conf.d/
有什么想法吗?请。
表 DDL:
CREATE TABLE `ps_hands` (
`id` bigint(14) NOT NULL DEFAULT '0',
`currency` tinyint(1) NOT NULL,
`handLimit` smallint(5) NOT NULL DEFAULT '0',
`date` date NOT NULL,
`maxPlayers` tinyint(1) NOT NULL,
`p1` mediumint(7) NOT NULL DEFAULT '0',
`p2` mediumint(7) NOT NULL DEFAULT '0',
`p3` mediumint(7) NOT NULL DEFAULT '0',
`p4` mediumint(7) NOT NULL DEFAULT '0',
`p5` mediumint(7) NOT NULL DEFAULT '0',
`p6` mediumint(7) NOT NULL DEFAULT '0',
`p7` mediumint(7) NOT NULL DEFAULT '0',
`p8` mediumint(7) NOT NULL DEFAULT '0',
`p9` mediumint(7) NOT NULL DEFAULT '0',
`pp1` mediumint(7) NOT NULL,
`pp2` mediumint(7) NOT NULL,
`pp3` mediumint(7) NOT NULL,
`pp4` mediumint(7) NOT NULL,
`pp5` mediumint(7) NOT NULL,
`pp6` mediumint(7) NOT NULL,
`pp7` mediumint(7) NOT NULL,
`pp8` mediumint(7) NOT NULL,
`pp9` mediumint(7) NOT NULL,
`psd1` tinyint(1) NOT NULL,
`psd2` tinyint(1) NOT NULL,
`psd3` tinyint(1) NOT NULL,
`psd4` tinyint(1) NOT NULL,
`psd5` tinyint(1) NOT NULL,
`psd6` tinyint(1) NOT NULL,
`psd7` tinyint(1) NOT NULL,
`psd8` tinyint(1) NOT NULL,
`psd9` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
KEY `maxPlayers` (`maxPlayers`),
KEY `p1_handLimit` (`p1`,`handLimit`),
KEY `p2_handLimit` (`p2`,`handLimit`),
KEY `p3_handLimit` (`p3`,`handLimit`),
KEY `p4_handLimit` (`p4`,`handLimit`),
KEY `p5_handLimit` (`p5`,`handLimit`),
KEY `p6_handLimit` (`p6`,`handLimit`),
KEY `p7_handLimit` (`p7`,`handLimit`),
KEY `p8_handLimit` (`p8`,`handLimit`),
KEY `p9_handLimit` (`p9`,`handLimit`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
查询说明:
+------+--------------+--------------------------+------+---------------+--------------+---------+-------+--------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+--------------------------+------+---------------+--------------+---------+-------+--------+----------------+
| 1 | PRIMARY | ps_hands | ref | p1_handLimit | p1_handLimit | 3 | const | 182239 | Using where |
| 2 | UNION | ps_hands | ref | p2_handLimit | p2_handLimit | 3 | const | 290077 | Using where |
| 3 | UNION | ps_hands | ref | p3_handLimit | p3_handLimit | 3 | const | 273151 | Using where |
| 4 | UNION | ps_hands | ref | p4_handLimit | p4_handLimit | 3 | const | 248191 | Using where |
| 5 | UNION | ps_hands | ref | p5_handLimit | p5_handLimit | 3 | const | 255685 | Using where |
| 6 | UNION | ps_hands | ref | p6_handLimit | p6_handLimit | 3 | const | 362813 | Using where |
| 7 | UNION | ps_hands | ref | p7_handLimit | p7_handLimit | 3 | const | 358672 | Using where |
| 8 | UNION | ps_hands | ref | p8_handLimit | p8_handLimit | 3 | const | 264515 | Using where |
| 9 | UNION | ps_hands | ref | p9_handLimit | p9_handLimit | 3 | const | 221512 | Using where |
| NULL | UNION RESULT | <union1,2,3,4,5,6,7,8,9> | ALL | NULL | NULL | NULL | NULL | NULL | Using filesort |
+------+--------------+--------------------------+------+---------------+--------------+---------+-------+--------+----------------+
【问题讨论】:
-
如果您想通过调整 SQL 查询来提高性能,那么这里就是发布您的慢速 SQL 查询的地方。但是,如果 SQL 编程对您来说只是一个黑匣子,并且您只想调整数据库的基础架构,那么您应该在 dba.stackexchange.com 上发布这个问题。
-
@TheImpaler,对不起,添加了查询到帖子。
-
date字段是否有索引? -
附加信息请求。在 pastebin.com 上发布并分享链接。文本结果: B) SHOW GLOBAL STATUS;至少 24 小时正常运行时间后 C) 显示全局变量; D) 显示完整的处理程序; E) 完整的 MySQLTuner 报告和可选的非常有用的信息,如果可用,包括 - htop OR top OR mytop 用于大多数活动应用程序,ulimit -a 用于 linux/unix 限制列表,iostat -xm 5 3 用于按设备和核心/cpu 的 IOPS计数,用于服务器工作负载调整分析。