Mysql

MySQL 伺服器重載

  • March 21, 2017

我有一台正在苦苦掙扎的 MySQL 5.1 伺服器。我們在某些​​表中有太多行,並且我們沒有足夠的 RAM - 目前只有 32 GB RAM。

我的 RAM 明天開始傳遞,但我要到週日才能安裝。從那時到現在(不刪除行)我想了解是否有任何調整可以考慮稍微提高性能。

最大的問題是我們有一張包含 32+ 百萬條記錄的表。對該表的任何選擇都需要相當長的時間(如您所料)。

我的假設是機器大量使用硬碟驅動器。但我也看到 mysqld 程序的 CPU 使用率很高。

我檢查了碎片表並優化了碎片表。

該伺服器有 10 個 HDD 在 RAID 10 陣列中工作。所以 I/O 有讀寫速度的提升。

InnoDB 讀取緩衝區效率:99.98%(35291508797 次點擊/總共 35299695194) InnoDB 寫入日誌效率:81.46%(36334605 次點擊/總共 44602585 次)

任何想法或建議將不勝感激。

這是 my.cfg 文件:

[mysqld]
innodb_file_per_table
skip-external-locking
port                            = 3306
socket                          = /var/lib/mysql/mysql.sock
max_connections                 = 256
key_buffer_size                 = 256M
max_allowed_packet              = 100M
table_open_cache                = 256
sort_buffer_size                = 1M
read_buffer_size                = 1M
read_rnd_buffer_size            = 4M
myisam_sort_buffer_size         = 64M
thread_cache_size               = 8
query_cache_size                = 16M
max_heap_table_size             = 512M
tmp_table_size                  = 512M
wait_timeout                    = 600
general_log_file                = /var/log/mysql/mysql.general.log
general_log                     = 0
log-slow-queries                = /var/log/mysql/mysql-slow.log
long_query_time                 = 60

# setup replication master:
server-id                       = 1
binlog-format                   = mixed
log-bin                         = /var/log/mysql/mysql-bin.log
datadir                         = /var/lib/mysql
innodb_flush_log_at_trx_commit  = 1
sync_binlog                     = 1

# InnoDB tables
innodb_flush_log_at_trx_commit  = 2
innodb_additional_mem_pool_size = 256M
innodb_buffer_pool_size         = 20G
innodb_lock_wait_timeout        = 120
innodb_log_buffer_size          = 32M
innodb_log_file_size            = 1024M

[mysqld_safe]
log-error                       = /var/log/mysqld.log
pid-file                        = /var/run/mysqld/mysqld.pid

[mysqldump]
quick
max_allowed_packet              = 16M

[mysql]
no-auto-rehash
prompt                          =\u:>\\_

[myisamchk]
key_buffer_size                 = 128M
sort_buffer_size                = 128M
read_buffer                     = 2M
write_buffer                    = 2M

[mysqlhotcopy]
interactive-timeout

我們有一個使用這個數據庫的應用程序。這個應用程序使用一個框架,對於頁面查詢,執行一個 count( ) 查詢來進行分頁。那些用於分頁的 count( ) 查詢是我看到的執行時間較長的查詢。

這是要求的資訊:


顯示表狀態:

| Name | Engine | Version | Row_format | Rows     | Avg_row_length | Data_length | Max_data_length   | Index_length | Data_free | Auto_increment | Create_time         | Update_time         | Check_time | Collation         | Checksum | Create_options | Comment |
| intz | InnoDB | 10      | Compact    | 37508536 |            562 | 21083717632 |                 0 |  15220752384 |   5242880 |       42680391 | 2016-07-26 12:05:22 | NULL                | NULL       | latin1_swedish_ci |     NULL | 

…看起來我們剛剛超過 20 GB。


選擇聲明:

SELECT 
   COUNT(*) AS count
FROM
  intz AS INTz
WHERE
   ((INTz.call_id_string LIKE '%3145551212%')
 OR (INTz.original_call_id LIKE '%3145551212%')
 OR (INTz.telephone_number LIKE '%3145551212%')
 OR (INTz.id = 3145551212)
 OR (INTz.ani LIKE '%3145551212%')
 OR (INTz.dnis LIKE '%3145551212%')
 OR (INTz.customer_account LIKE '%3145551212%'));

… select count(*) 大約需要 75 秒才能執行。


解釋選擇:

+----+-------------+-------------+-------+-----------------+--------------+---------+------+----------+--------------------------+
| id | select_type | table | type  | possible_keys   | key          | key_len | ref  | rows     | Extra                    |
+----+-------------+-------------+-------+-----------------+--------------+---------+------+----------+--------------------------+
|  1 | SIMPLE      | intz  | index | id,search_index | search_index | 313     | NULL | 40707970 | Using where; Using index |
+----+-------------+-------------+-------+-----------------+--------------+---------+------+----------+--------------------------+

我在這些欄位上也有一個索引:

alter table intz add index search_index (id,call_id_string,original_call_id,telephone_number,ani,dnis,customer_account);

高 CPU 和/或 I/O - 找到最慢的查詢,提供它們,加上EXPLAIN SELECT ...SHOW CREATE TABLE. 這是最有可能解決您的問題的方法。 修復可能很簡單,例如添加“複合”索引。

桌子有多大?( SHOW TABLE STATUS) 如果小於 20GB,額外的 RAM 可能無濟於事。

對於 32GB 的 RAM,這些設置是合理的。添加更多後,請務必(僅)innodb_buffer_pool_size增加到大約 70% 的 RAM。

PARTITIONing附帶 5.1。但是,它提供任何性能優勢的情況很少。在盲目開始之前,讓我們先看看查詢和模式。順便說一句,直到 5.1.43 才添加了這個構造:PARTITION BY RANGE(UNIX_TIMESTAMP(col))。 更多關於分區。

附加物

ORLIKE使用前導萬用字元 == 表掃描(或您的情況下的索引掃描)。索引沒有多大幫助,因為它幾乎和表格一樣大。

添加一個額外的列(或者可能是一個額外的表),其中包含這些搜尋列的串聯。在上面建立一個FULLTEXT索引。然後用 搜尋MATCH(combined_col) AGAINST (+3145551212 IN BOOLEAN MODE)。它將執行一千倍的速度;“成本”將消失。你會後悔購買額外的記憶體。

將它用於您的查詢和計數。

但是有一些限制(字長、“字”的定義等)。

引用自:https://dba.stackexchange.com/questions/167653