
สารบัญ
MySQL และ MariaDB เป็นฐานข้อมูลที่ใช้งานบน VPS มากที่สุด แต่ค่าเริ่มต้น (default) ที่มาพร้อมการติดตั้งมักถูกออกแบบมาสำหรับเครื่องที่มี RAM น้อย ไม่เหมาะกับ VPS ในยุคปัจจุบัน บทความนี้จะพาคุณปรับค่าทีละขั้นตอนเพื่อให้ได้ประสิทธิภาพสูงสุด
ทำไม MySQL ถึงช้า
ก่อนปรับแต่ง เราต้องเข้าใจก่อนว่าปัญหาหลักของ MySQL/MariaDB ที่ติดตั้งใหม่คืออะไร:
| ปัญหา | สาเหตุ | ผลกระทบ |
|---|---|---|
| innodb_buffer_pool_size เล็กเกิน | ค่า default 128MB | อ่าน disk บ่อย ช้ามาก |
| max_connections สูงเกิน | จอง RAM ล่วงหน้า | RAM ล้น swap เยอะ |
| ไม่มี index ที่เหมาะสม | ไม่เคย EXPLAIN query | full table scan ทุก query |
| query_cache_type ปิด | ค่า default MySQL 8 | คำนวณซ้ำทุกครั้ง |
| log_bin เปิดโดยไม่จำเป็น | ค่า default บางตัว | เปลือง disk I/O |
ปรับ InnoDB Buffer Pool
InnoDB buffer pool คือส่วนที่สำคัญที่สุดในการ tune MySQL — มันทำหน้าที่ cache ข้อมูลและ index จาก disk ไว้ใน RAM ยิ่งใหญ่ยิ่งดี (ภายในขอบเขตที่ RAM อนุญาต)
สูตรง่าย: ตั้ง innodb_buffer_pool_size ที่ 50–70% ของ RAM ทั้งหมด เหลือไว้ให้ OS, PHP, web server
| RAM VPS | ค่าแนะนำ |
|---|---|
| 2 GB | 1G |
| 4 GB | 2G–2.5G |
| 8 GB | 4G–5G |
| 16 GB | 8G–10G |
ตรวจสอบการใช้งานปัจจุบัน:
mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
mysql -u root -p -e "SHOW STATUS LIKE 'Innodb_buffer_pool_reads';"
ตั้งค่า my.cnf ที่สำคัญ
ไฟล์ config หลักของ MySQL/MariaDB อยู่ที่ /etc/mysql/my.cnf หรือ /etc/my.cnf ขึ้นอยู่กับ distro
[mysqld]
# Buffer Pool — ปรับตาม RAM ที่มี
innodb_buffer_pool_size = 2G
innodb_buffer_pool_instances = 2
# Log File — ใหญ่ขึ้น = checkpoint น้อยลง
innodb_log_file_size = 256M
innodb_log_buffer_size = 16M
# I/O Settings
innodb_flush_log_at_trx_commit = 2 # ลด I/O (ยอมเสี่ยง ข้อมูล 1 วินาที)
innodb_flush_method = O_DIRECT # ลด double buffering กับ OS
# Connections
max_connections = 150 # ลดจาก default 151-200
thread_cache_size = 16
# Query Cache (MariaDB เท่านั้น — MySQL 8 ถอดแล้ว)
# query_cache_type = 1
# query_cache_size = 64M
# query_cache_limit = 2M
# Tmp Tables
tmp_table_size = 64M
max_heap_table_size = 64M
# Slow Query Log (เปิดไว้เพื่อ tune)
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
# Binary Log — ปิดถ้าไม่ได้ใช้ replication
# skip-log-bin
⚠️ สำหรับ MySQL 8.0: query_cache ถูกถอดออกแล้ว ห้ามใส่ไม่งั้น MySQL จะ start ไม่ได้ ถ้าใช้ MariaDB 10.x ยังใส่ได้
หลังแก้ไขแล้ว restart MySQL:
sudo systemctl restart mysql
# หรือสำหรับ MariaDB
sudo systemctl restart mariadb
เปิด Slow Query Log
Slow query log คือเครื่องมือที่ทรงพลังมากสำหรับการหา query ที่เป็นต้นเหตุความช้า ควรเปิดไว้เสมอในช่วง optimize
# ตรวจสอบว่า slow log เปิดอยู่หรือยัง
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
# เปิด real-time โดยไม่ต้อง restart
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
วิเคราะห์ slow log ด้วย mysqldumpslow:
# แสดง 10 query ที่ช้าที่สุด
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
# แสดง query ที่รันซ้ำบ่อยสุด
mysqldumpslow -s c -t 10 /var/log/mysql/slow.log
ปรับ Index และ Query
Index ที่ดีสามารถเพิ่มความเร็ว query ได้ 100–1000 เท่า ใช้ EXPLAIN เพื่อตรวจสอบว่า query ใช้ index หรือไม่
-- ตรวจสอบ query plan
EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND status = 'pending';
-- ดู index ที่มีอยู่
SHOW INDEX FROM orders;
-- เพิ่ม composite index
ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);
-- ลบ index ที่ไม่ใช้
DROP INDEX old_index_name ON orders;
เคล็ดลับ: ดู column type ใน EXPLAIN — ถ้าเป็น ALL แปลว่า full table scan ต้องเพิ่ม index ด่วน
ตรวจหา index ที่ไม่ถูกใช้งาน
-- MySQL 8 / MariaDB 10.6+
SELECT * FROM sys.schema_unused_indexes
WHERE object_schema NOT IN ('performance_schema','mysql','sys','information_schema');
ใช้ MySQLTuner
MySQLTuner เป็น script ที่วิเคราะห์ MySQL/MariaDB และแนะนำค่าที่ควรปรับโดยอัตโนมัติ ควรรันหลังจาก server ทำงานมาแล้วอย่างน้อย 24 ชั่วโมงเพื่อให้ข้อมูลเพียงพอ
# ติดตั้ง
wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl
# รัน
perl mysqltuner.pl --user root --pass your_password
# หรือรันแบบไม่ต้องใส่ password (อ่านจาก ~/.my.cnf)
perl mysqltuner.pl
ผลลัพธ์จะแสดง:
- [!!] — ปัญหาที่ต้องแก้ไขด่วน
- [OK] — ค่าที่ดีอยู่แล้ว
- Variables to adjust — รายการค่าที่ควรปรับพร้อมตัวเลขแนะนำ
MariaDB vs MySQL
สำหรับ VPS ใหม่แนะนำ MariaDB เพราะมีข้อดีหลายประการ:
| คุณสมบัติ | MySQL 8.0 | MariaDB 10.11 |
|---|---|---|
| Query Optimizer | ดี | ดีกว่าหลาย use case |
| Query Cache | ถอดออกแล้ว | ยังมี (optional) |
| JSON Support | Native JSON type | Dynamic columns + JSON |
| Storage Engines | InnoDB, MyISAM | InnoDB, Aria, ColumnStore |
| Galera Cluster | ต้องใช้ plugin เพิ่ม | รองรับ built-in |
| License | GPL/Commercial | GPL (open) |
การ Monitor ประสิทธิภาพ
หลังจากปรับค่าแล้ว ควร monitor อย่างต่อเนื่องเพื่อดูผล:
# ดู status real-time
mysqladmin -u root -p status
# ดู process list
SHOW PROCESSLIST;
# ดู global status ที่สำคัญ
SHOW GLOBAL STATUS LIKE 'Questions';
SHOW GLOBAL STATUS LIKE 'Slow_queries';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads';
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Aborted_connects';
คำนวณ Buffer Pool Hit Rate
-- Hit rate ควรสูงกว่า 99%
SELECT
(1 - (Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests)) * 100
AS buffer_pool_hit_rate
FROM (
SELECT
VARIABLE_VALUE AS Innodb_buffer_pool_reads
FROM information_schema.GLOBAL_STATUS
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads'
) r,
(
SELECT
VARIABLE_VALUE AS Innodb_buffer_pool_read_requests
FROM information_schema.GLOBAL_STATUS
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests'
) rr;
Checklist สรุป
| รายการ | สิ่งที่ต้องทำ |
|---|---|
| innodb_buffer_pool_size | ตั้งที่ 50-70% ของ RAM |
| slow_query_log | เปิดและตั้ง long_query_time = 2 |
| max_connections | ลดให้พอดีกับ load จริง |
| index | รัน EXPLAIN กับ query หลัก |
| tmp_table_size | ตั้งที่ 64M เพื่อลด disk tmp table |
| MySQLTuner | รันหลัง 24 ชั่วโมงและ apply คำแนะนำ |
| binary log | ปิดถ้าไม่ได้ใช้ replication |
| Buffer Pool Hit Rate | ต้องสูงกว่า 99% |
คำถามที่พบบ่อย
ทำไม MySQL บน VPS ถึงช้า?
สาเหตุหลักคือค่าเริ่มต้นของ MySQL ถูกออกแบบมาสำหรับเครื่อง RAM น้อย ไม่ใช่ VPS สมัยใหม่ ต้องปรับ InnoDB buffer pool, max_connections และ slow query log ให้เหมาะกับ RAM ที่มี
InnoDB buffer pool ควรตั้งค่าเท่าไหร่?
แนะนำให้ตั้งที่ 50-70% ของ RAM ทั้งหมด เช่น VPS RAM 4GB ให้ตั้ง innodb_buffer_pool_size = 2G ระวังอย่าตั้งสูงเกินไปจนระบบขาด RAM สำหรับ process อื่น
slow query log คืออะไรและใช้ประโยชน์อะไร?
slow query log คือ log ที่บันทึก query ที่ใช้เวลานานกว่าที่กำหนด ช่วยระบุ query ที่ต้องปรับ index หรือ rewrite เพื่อเพิ่มประสิทธิภาพ
MariaDB ดีกว่า MySQL อย่างไร?
MariaDB เป็น fork ของ MySQL ที่มีประสิทธิภาพสูงกว่าในบางกรณี โดยเฉพาะ optimizer ที่ฉลาดกว่า รองรับ storage engine มากกว่า และ community ที่ active ใน Linux ecosystem
ควรใช้ mysqltuner หรือ tuning-primer สำหรับ VPS?
ทั้งสองเครื่องมือมีประโยชน์ mysqltuner เหมาะสำหรับการตรวจสอบเบื้องต้นและแนะนำค่าที่ควรปรับ ส่วน tuning-primer ให้ข้อมูลละเอียดกว่า แนะนำรันหลังจาก server ทำงานมาแล้วอย่างน้อย 24 ชั่วโมง
ควร restart MySQL หลังแก้ my.cnf หรือไม่?
ค่าส่วนใหญ่ต้อง restart MySQL เพื่อให้มีผล บางค่าสามารถ SET GLOBAL ได้โดยไม่ต้อง restart แต่จะหายเมื่อ restart ควรแก้ my.cnf ก่อนแล้วค่อย restart เพื่อให้ถาวร