ใช้ EXPLAIN วิเคราะห์ ORDER BY Performance
EXPLAIN แสดง Execution Plan ของ Query ช่วยดูว่า MySQL ใช้ Index, Filesort, หรือ Temporary Table
ตัวอย่างตาราง
CREATE TABLE DemoTable606 (
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
FirstName VARCHAR(100)
);
INSERT INTO DemoTable606(FirstName) VALUES
('John'), ('Robert'), ('Chris'), ('David');
Case 1: ORDER BY Primary Key (Index Scan - เร็วที่สุด)
EXPLAIN SELECT * FROM DemoTable606 ORDER BY Id;
+----+-------------+--------------+-------+---------------+---------+---------+------+------+----------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------+-------+---------------+---------+---------+------+------+----------+-------+
| 1 | SIMPLE | DemoTable606 | index | NULL | PRIMARY | 4 | NULL | 4 | 100.00 | NULL |
+----+-------------+--------------+-------+---------------+---------+---------+------+------+----------+-------+
Extra: NULL = ไม่มี Filesort ใช้ Index เรียงได้เลย (Index Scan)
Case 2: ORDER BY Primary Key + Column อื่น (Filesort)
EXPLAIN SELECT * FROM DemoTable606 ORDER BY Id, FirstName;
+----+-------------+--------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------+------+---------------+------+---------+------+------+----------+----------------+
| 1 | SIMPLE | DemoTable606 | ALL | NULL | NULL | NULL | NULL | 4 | 100.00 | Using filesort |
+----+-------------+--------------+------+---------------+------+---------+------+------+----------+----------------+
Extra: Using filesort = ต้อง Sort ใน Memory/Disk เพราะ Index (Id) ไม่ครอบคลุม FirstName
Case 3: ORDER BY Id, RAND() (Temporary Table + Filesort)
EXPLAIN SELECT * FROM DemoTable606 ORDER BY Id, RAND();
+----+-------------+--------------+------+---------------+------+---------+------+------+----------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------+------+---------------+------+---------+------+------+----------+---------------------------------+
| 1 | SIMPLE | DemoTable606 | ALL | NULL | NULL | NULL | NULL | 4 | 100.00 | Using temporary; Using filesort |
+----+-------------+--------------+------+---------------+------+---------+------+------+----------+---------------------------------+
Extra: Using temporary; Using filesort = สร้าง Temp Table แล้ว Sort (ช้ามาก)
สรุป Extra Column ความหมาย
| Extra Value | ความหมาย | Performance |
|---|---|---|
| NULL | ใช้ Index เรียงได้ ไม่ต้อง Sort เพิ่ม | 🟢 ดีที่สุด |
| Using index | Covering Index (Select เฉพาะ Column ใน Index) | 🟢 ดีมาก |
| Using filesort | ต้อง Sort เพิ่ม (Memory/Disk) | 🟡 ปานกลาง-ช้า |
| Using temporary | สร้าง Temp Table (Memory/Disk) | 🔴 ช้า |
| Using temporary; Using filesort | Temp Table + Sort (Slowest) | 🔴 ช้ามาก |
วิธีหลีกเลี่ยง Filesort
- Composite Index:
INDEX idx_id_name (Id, FirstName)ครอบคลุม ORDER BY - Covering Index: SELECT เฉพาะ Column ใน Index
- LIMIT น้อย: MySQL ใช้ Priority Queue แทน Full Sort
- ไม่ใช้ RAND() ใน ORDER BY: บังคับ Temp Table + Filesort เสมอ
ตัวอย่างสร้าง Index ป้องกัน Filesort
ALTER TABLE DemoTable606 ADD INDEX idx_id_firstname (Id, FirstName);
-- ทดสอบใหม่
EXPLAIN SELECT * FROM DemoTable606 ORDER BY Id, FirstName;
-- Extra จะกลายเป็น NULL (ใช้ Index)