2

I have 2 main tables on the server. They have the same structure, but hold different data.

Table #1: 214 million rows, size 40GB (25gb indexes)

Table #2: 26 million rows, size 5.5GB (3.5gb indexes)

My OS is Debian 8 Jessie.

The first problem. Everything works very quickly when there is a cache in memory. If I clean cache or reboot the server, then MySQL queries are very slow. MySQL stores indexes in memory and takes it as a cache, always? Because after some manipulations, the select queries is very fast. What manipulations need to be done to make the server fly:

If I using duplicate of table #1, then during its execution, as I understand it, a read operation occurs and at the same time the information is cached into memory. Here is a free -m screen at the moment of launching a duplicate table.

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

The result, when the duplicate table was created:

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 of RAM under the cache. Execution of the query before the duplicate table 105 seconds:

# 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;

After the duplicate table, it's 0.2 seconds instead 105 secs.

I am thinking of changing the disk from SSHD to NVMe M2 (5x faster). But I will have another 4-5 tables of 50GB each, in this case, I just do not have enough RAM.

I have 128GB RAM. In addition to this project, there is one more project. On which 50GB are allocated. The rest is used for this project and MySQL. I use MyISAM and not InnoDB, because on the site only selects and inserts operations. InnoDB is 20 times slower, checked on a home machine, too, with an M.2 disk....

Here is the mysql config file:

[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/

Table 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;

Query explain:

+------+--------------+--------------------------+------+---------------+--------------+---------+-------+--------+----------------+
| 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 |
+------+--------------+--------------------------+------+---------------+--------------+---------+-------+--------+----------------+

I have same values in p1-p9 , its a player IDs. One player can have 20 rows, or can have 2 million rows. Most often I get the data exactly by p1-p9 or p1-p9 and handLimit. Sometimes a date is involved, but it’s in every row and I don’t see any reason to index date. How to be?

14
  • 1
    @RDFozz I'm sorry, I meant that the tables are identical in structure and only for individual users upon their request. And there will be 4-5 more such tables in the future. But the data in the tables are different. Therefore, one weighs more than the second. Because it has more data. – 8power Oct 10 '18 at 20:35
  • 1
    @danblack no, i use DEMAND cache, and rarely use SQL_CACHE.. (auto-cache disabled) – 8power Oct 10 '18 at 22:00
  • 1
    @danblack no, after slowlog i checked separately in MySQL Workbench without using SQL_CACHE, it happened because the indexes were already in the RAM cache after query from slowlog. – 8power Oct 10 '18 at 22:07
  • 1
    @WilsonHauck all my options before changes about what you said: pastebin.com/iLXhHG4v and my new options after your post: pastebin.com/uQWrYWXx – 8power Oct 10 '18 at 23:28
  • 2
    @WilsonHauck after I put your settings MySQL began to slow down. I think this is due to the fact that I reduced the key_buffer_size from 55GB to 26GB (20% as you said). Now the usual query to select from the table is loaded 76 seconds instead 1 second. # Query_time: 76.709949 Lock_time: 0.000180 Rows_sent: 34130 Rows_examined: 1168846 – 8power Oct 10 '18 at 23:31
1

Suggestions to consider for your my.cnf [mysqld] section Rate Per Second=RPS

20181011 05 00 from mysqlservertuning.com
review your code for presence of CLOSE() at end of session to release threads_connected
innodb_log_file_size=32M  # from 5M should NEVER be less than buffer size
    special handling required on this VERY old v5.5.39 see REFMAN
max_connections=200  # from 500 until you NEED more connections
innodb_io_capacity=15000  # from 200 to use more of your IOPS capacity
read_buffer_size=128K  # from 128M to reduce handler_read_rnd_next RPS dramatically
sort_buffer_size=2M  # from ~ 512M to reduce PER connection RAM requirement
max_write_lock_count=16  # from ~4 billion to allow RD after nn lock requests
table_open_cache=10000  # from 2048 to reduce opened_tables count
table_definition_cache=3000  # from 400 to reduce opened_table_definitions count
open_files_limit=24000  # from 10000 to reduce opened_files RPS
key_buffer_size=12G  # from 24G because less than 10% used
key_cache_age_threshold=7200  # from 300 seconds to minimize AGE OUT data
key_cache_division_limit=50  # from 100 percent for Hot/Warm caches
key_cache_block_size=16384  # from 1024 to reduce CPU cycles for mgmt
query_cache_type=0  # from DEMAND for OFF less than 1% are CACHED
query_cache_size=0  # from 256M to conserve RAM and CPU cycles for mgmt

Other observed difficulties

rollback avg 1 every 45 seconds for this day; slow queries of 299 per hour should be cleaned up

For additional suggestions view my profile, Network profile for contact information including my Skype ID and get in touch, please.

2
  • @8power Have you VERIFIED you are using CLOSE() when your session is completed AND applied the suggestions of Oct 11, 2018 at 9:51 to your configuration? – Wilson Hauck Oct 17 '18 at 11:11
  • @8power How is your system performing at this time? – Wilson Hauck Aug 17 '20 at 15:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.