- 1 1. บทนำ
- 2 2. ความแตกต่างระหว่าง EXPLAIN และ EXPLAIN ANALYZE
- 3 3. รูปแบบผลลัพธ์ของ EXPLAIN ANALYZE
- 4 4. How to Interpret Execution Plans
- 5 5. ตัวอย่างการปรับแต่งคิวรีเชิงปฏิบัติ
- 6 6. Precautions and Best Practices
- 7 7. Frequently Asked Questions (FAQ)
- 7.1 Q1. From which version is EXPLAIN ANALYZE available?
- 7.2 Q2. Can running EXPLAIN ANALYZE modify data?
- 7.3 Q3. Isn’t EXPLAIN alone sufficient?
- 7.4 Q4. How accurate are values like “loops” and “actual time”?
- 7.5 Q5. “cost” หมายถึงอะไรอย่างแท้จริง?
- 7.6 Q6. ประโยชน์ของการใช้รูปแบบ JSON หรือ TREE คืออะไร?
- 7.7 Q7. ควรทำอย่างไรหากไม่สามารถปรับปรุงประสิทธิภาพได้หลังจากตรวจสอบแผนการดำเนินการ?
1. บทนำ
แผนการดำเนินงาน: สิ่งจำเป็นสำหรับการเพิ่มประสิทธิภาพฐานข้อมูล
ในแอปพลิเคชันเว็บและระบบธุรกิจ ประสิทธิภาพของฐานข้อมูลเป็นปัจจัยสำคัญที่ส่งผลโดยตรงต่อเวลาในการตอบสนองโดยรวม เมื่อใช้ MySQL โดยเฉพาะ การเข้าใจ “execution plan” เป็นสิ่งจำเป็นสำหรับการประเมินประสิทธิภาพของคิวรี คำสั่ง EXPLAIN แบบดั้งเดิมจะแสดงแผนการดำเนินงานก่อนรันคำสั่ง SQL และได้ให้ข้อมูลเชิงลึกที่มีค่าแก่ผู้พัฒนามานาน
“EXPLAIN ANALYZE” ที่แนะนำใน MySQL 8.0
แนะนำใน MySQL 8.0.18, EXPLAIN ANALYZE เป็นการปรับปรุงที่ทรงพลังของ EXPLAIN แบบดั้งเดิม ในขณะที่ EXPLAIN ให้เพียง “แผนทฤษฎี” เท่านั้น EXPLAIN ANALYZE จะทำการรันคิวรีจริงและคืนค่า ข้อมูลที่วัดได้ เช่น เวลาในการดำเนินงานและจำนวนแถวที่ประมวลผล ซึ่งทำให้สามารถระบุคอขวดได้อย่างแม่นยำยิ่งขึ้นและตรวจสอบผลลัพธ์ของการปรับแต่งคิวรี
ทำไม EXPLAIN ANALYZE ถึงสำคัญ
ตัวอย่างเช่น ลำดับการ JOIN, การใช้ดัชนี, และเงื่อนไขการกรอง มีผลอย่างมากต่อเวลาในการดำเนินงาน โดยการใช้ EXPLAIN ANALYZE คุณสามารถยืนยันด้วยภาพว่าคำสั่ง SQL ทำงานอย่างไรและระบุว่ามีส่วนใดที่ไม่มีประสิทธิภาพและควรปรับแต่งอะไร นี่เป็นสิ่งที่ขาดไม่ได้โดยเฉพาะเมื่อทำงานกับชุดข้อมูลขนาดใหญ่หรือคิวรีที่ซับซ้อน
จุดประสงค์ของบทความนี้และกลุ่มเป้าหมาย
บทความนี้อธิบายทุกอย่างตั้งแต่พื้นฐานของ EXPLAIN ANALYZE ของ MySQL ไปจนถึงการตีความผลลัพธ์และการนำเทคนิคการปรับแต่งที่ใช้งานได้จริงมาใช้ มุ่งเน้นไปที่นักพัฒนาและวิศวกรโครงสร้างพื้นฐานที่ใช้ MySQL อย่างสม่ำเสมอ รวมถึงวิศวกรที่สนใจการปรับจูนประสิทธิภาพ เพื่อให้เข้าใจง่ายแม้สำหรับผู้เริ่มต้น เราได้รวมคำอธิบายคำศัพท์และตัวอย่างที่เป็นรูปธรรมตลอดบทความ
2. ความแตกต่างระหว่าง EXPLAIN และ EXPLAIN ANALYZE
บทบาทและการใช้งานพื้นฐานของ EXPLAIN
EXPLAIN ของ MySQL เป็นเครื่องมือวิเคราะห์ที่ใช้เพื่อทำความเข้าใจล่วงหน้าว่าคำสั่ง SQL (โดยเฉพาะคำสั่ง SELECT) จะถูกดำเนินการอย่างไร มันช่วยให้คุณยืนยันแผนการดำเนินงานเช่นการใช้ดัชนี, ลำดับการ join, และช่วงการค้นหา
ตัวอย่างเช่น
EXPLAIN SELECT * FROM users WHERE age > 30;
เมื่อคำสั่งนี้ถูกเรียกใช้ MySQL จะไม่รันคิวรีจริง แต่จะแสดงว่ามันวางแผนจะประมวลผลอย่างไรในรูปแบบตาราง ผลลัพธ์จะรวมข้อมูลเช่นดัชนีที่ใช้ (key), วิธีการเข้าถึง (type), และจำนวนแถวที่คาดการณ์ (rows).
บทบาทและคุณลักษณะของ EXPLAIN ANALYZE
ในทางตรงกันข้าม EXPLAIN ANALYZE ที่แนะนำใน MySQL 8.0.18 จะรันคิวรีและแสดงแผนการดำเนินงานโดยอิงจากค่าที่วัดได้จริง ซึ่งทำให้สามารถยืนยันรายละเอียดที่ไม่ปรากฏใน EXPLAIN แบบดั้งเดิม เช่น เวลาในการประมวลผลจริงและจำนวนแถวที่ประมวลผลจริง
ตัวอย่าง:
EXPLAIN ANALYZE SELECT * FROM users WHERE age > 30;
คำสั่งนี้รันคิวรีและคืนผลลัพธ์ที่รวมถึง:
- เวลาในการดำเนินการของแต่ละขั้นตอนในแผน (เช่น
0.0022 sec) - จำนวนแถวที่อ่านจริง (
rows) - โครงสร้างการประมวลผล (สามารถมองเห็นได้ง่ายโดยใช้รูปแบบ TREE)
สรุปความแตกต่างสำคัญ
| Item | EXPLAIN | EXPLAIN ANALYZE |
|---|---|---|
| Query Execution | Does not execute | Executes the query |
| Information Provided | Estimated information before execution | Measured information after execution |
| Primary Use | Checking indexes and join order | Actual performance analysis |
| MySQL Version | Available since early versions | MySQL 8.0.18 or later |
ควรใช้อันไหน?
- ใช้
EXPLAINเมื่อคุณต้องการตรวจสอบโครงสร้างคิวรีอย่างรวดเร็ว - ใช้
EXPLAIN ANALYZEเมื่อคุณต้องการรายละเอียดที่เป็นรูปธรรมเกี่ยวกับเวลาในการดำเนินงานและต้นทุนของคิวรี
โดยเฉพาะในสถานการณ์การปรับจูนประสิทธิภาพ EXPLAIN ANALYZE ทำให้การปรับแต่งอิงจากข้อมูลการดำเนินงานจริงแทนการประมาณค่า ทำให้เป็นเครื่องมือที่ทรงพลังอย่างยิ่ง
3. รูปแบบผลลัพธ์ของ EXPLAIN ANALYZE
สามรูปแบบผลลัพธ์: TRADITIONAL, JSON, และ TREE
EXPLAIN ANALYZE ของ MySQL สามารถแสดงผลลัพธ์ในรูปแบบต่าง ๆ ตามวัตถุประสงค์ของคุณ ใน MySQL 8.0 ขึ้นไป มีรูปแบบต่อไปนี้ให้เลือกใช้สามแบบ
| Format | Features | Ease of Use |
|---|---|---|
| TRADITIONAL | Classic table-style output. Familiar and easy to read | Beginner-friendly |
| JSON | Provides structured, detailed information | Best for tooling and integrations |
| TREE | Makes nested structure visually clear | Intermediate to advanced |
มาดูความแตกต่างอย่างละเอียดกัน
รูปแบบ TRADITIONAL (ค่าเริ่มต้น)
TRADITIONAL output คล้ายกับสไตล์ EXPLAIN แบบคลาสสิก และช่วยให้คุณตรวจสอบแผนการรันได้ในรูปแบบที่คุ้นเคย หากคุณรัน EXPLAIN ANALYZE โดยไม่ระบุรูปแบบ ผลลัพธ์จะแสดงในรูปแบบนี้โดยทั่วไป
ตัวอย่างผลลัพธ์ (บางส่วน):
-> Filter: (age > 30) (cost=0.35 rows=10) (actual time=0.002..0.004 rows=8 loops=1)
cost: ค่าใช้จ่ายที่ประมาณการactual time: เวลาที่วัดได้จริงrows: จำนวนแถวที่ประมาณการว่าจะประมวลผล (ก่อนการรัน)loops: จำนวนลูป (สำคัญมากสำหรับ JOIN)
รูปแบบ TRADITIONAL ง่ายต่อการสแกนและเข้าใจสำหรับมนุษย์ ทำให้เหมาะสำหรับผู้เริ่มต้นและการตรวจสอบอย่างรวดเร็ว
JSON Format
รูปแบบ JSON มีรายละเอียดมากกว่าและจัดการด้วยโปรแกรมได้ง่ายกว่า ผลลัพธ์มีโครงสร้าง โดยแต่ละโหนดแสดงเป็นออบเจ็กต์แบบซ้อนกัน
คำสั่ง:
EXPLAIN ANALYZE FORMAT=JSON SELECT * FROM users WHERE age > 30;
ส่วนหนึ่งของผลลัพธ์ (จัดรูปแบบให้สวยงาม):
{
"query_block": {
"table": {
"table_name": "users",
"access_type": "range",
"rows_examined_per_scan": 100,
"actual_rows": 80,
"filtered": 100,
"cost_info": {
"query_cost": "0.35"
},
"timing": {
"start_time": 0.001,
"end_time": 0.004
}
}
}
}
รูปแบบนี้ไม่ค่อยอ่านง่ายทางสายตา แต่สะดวกมากเมื่อคุณต้องการแยกวิเคราะห์ข้อมูลและป้อนลงในเครื่องมือวิเคราะห์หรือแดชบอร์ด
TREE Format (อ่านง่ายและเหมาะสำหรับการแสดงโครงสร้างแบบภาพ)
รูปแบบ TREE แสดงโครงสร้างการรันคำสั่งค้นหาในรูปแบบต้นไม้ ทำให้เข้าใจลำดับการประมวลผล JOIN และ subquery ได้ง่ายขึ้น
คำสั่ง:
EXPLAIN ANALYZE FORMAT=TREE SELECT * FROM users WHERE age > 30;
ตัวอย่างผลลัพธ์ (ย่อ):
-> Table scan on users (actual time=0.002..0.004 rows=8 loops=1)
สำหรับคำสั่งค้นหาที่ซับซ้อน การซ้อนกันอาจปรากฏเช่นนี้:
-> Nested loop join
-> Table scan on users
-> Index lookup on orders using idx_user_id
รูปแบบ TREE มีประโยชน์มากสำหรับคำสั่งค้นหาที่มี JOIN หลายตัวหรือการซ้อนที่ซับซ้อน ซึ่งคุณต้องการเข้าใจกระบวนการประมวลผล
Which Format Should You Use?
| Use Case | Recommended Format |
|---|---|
| Beginner and want a simple view | TRADITIONAL |
| Want to analyze programmatically | JSON |
| Want to understand structure and nesting | TREE |
เลือกใช้รูปแบบที่เหมาะกับเป้าหมายของคุณ และตรวจสอบแผนการรันในสไตล์ที่อ่านง่ายและวิเคราะห์ได้ดีที่สุด
4. How to Interpret Execution Plans
Why You Need to Read Execution Plans
ประสิทธิภาพคำสั่งค้นหา MySQL สามารถแตกต่างกันมากขึ้นอยู่กับปริมาณข้อมูลและความพร้อมของดัชนี โดยการตีความผลลัพธ์แผนการรันจาก EXPLAIN ANALYZE อย่างถูกต้อง คุณสามารถระบุได้อย่างเป็นกลางว่าการทำงานสูญเปล่าที่ใดและควรปรับปรุงอะไร ทักษะนี้เป็นรากฐานของการปรับแต่งประสิทธิภาพ โดยเฉพาะสำหรับคำสั่งค้นหาที่จัดการชุดข้อมูลขนาดใหญ่หรือการเชื่อมต่อที่ซับซ้อน
Basic Structure of an Execution Plan
ผลลัพธ์ของ EXPLAIN ANALYZE รวมข้อมูลเช่นต่อไปนี้ (อธิบายที่นี่โดยอิงจากผลลัพธ์สไตล์ TRADITIONAL):
-> Filter: (age > 30) (cost=0.35 rows=10) (actual time=0.002..0.004 rows=8 loops=1)
บรรทัดเดียวนี้มีฟิลด์สำคัญหลายตัว
| Field | Description |
|---|---|
| Filter | Filtering step for conditions such as WHERE clauses |
| cost | Estimated cost before execution |
| rows | Estimated number of processed rows (before execution) |
| actual time | Measured elapsed time (start to end) |
| actual rows | Actual number of processed rows |
| loops | How many times this step was repeated (important for nested operations) |
How to Read Key Fields
1. cost vs. actual time
costคือการประมาณการภายในที่คำนวณโดย MySQL และใช้สำหรับการประเมินเชิงสัมพัทธ์actual timeสะท้อนเวลาที่ผ่านไปจริงและสำคัญมากกว่าสำหรับการวิเคราะห์ประสิทธิภาพ
ตัวอย่าง:
(cost=0.35 rows=100) (actual time=0.002..0.004 rows=100)
หากการประมาณการและการวัดใกล้เคียงกัน แผนการรันน่าจะแม่นยำ หากช่องว่างใหญ่ สถิติตารางอาจไม่ถูกต้อง
2. rows vs. actual rows
rowsคือจำนวนแถวที่ MySQL คาดว่าจะอ่านactual rowsคือจำนวนแถวที่อ่านจริง (รวมอยู่ในวงเล็บในผลลัพธ์สไตล์ TRADITIONAL)
หากมีความแตกต่างมาก คุณอาจต้องอัปเดตสถิติหรือพิจารณาการออกแบบดัชนีใหม่
3. loops
If loops=1 ขั้นตอนจะทำงานหนึ่งครั้ง หากใช้ JOIN หรือ subquery คุณอาจเห็น loops=10 หรือ loops=1000 ค่าที่ใหญ่ขึ้นหมายความว่าการวนลูปซ้อนกันอาจทำให้การประมวลผลหนักขึ้น.
ทำความเข้าใจโครงสร้างซ้อนของแผนการดำเนินการ
เมื่อมีการเชื่อมหลายตาราง แผนการดำเนินการจะแสดงเป็นต้นไม้ (โดยเฉพาะอย่างชัดเจนในรูปแบบ TREE).
Example:
-> Nested loop join
-> Table scan on users
-> Table scan on orders
ปัญหา
- ทั้งสองตารางถูกสแกนเต็มที่ ส่งผลให้ค่าใช้จ่ายการเชื่อมสูง
มาตรการแก้ไข
- เพิ่มดัชนีบน
users.ageและกรองล่วงหน้าเพื่อลดภาระการเชื่อม
วิธีการระบุคอขวดประสิทธิภาพ
การมุ่งเน้นที่จุดต่อไปนี้ทำให้การค้นหาคอขวดง่ายขึ้น:
- โหนดที่มีเวลาจริงยาวและจำนวนแถวมาก : สิ่งเหล่านี้ใช้เวลาการดำเนินการส่วนใหญ่
- จุดที่เกิดการสแกนตารางเต็ม : มีแนวโน้มว่าดัชนีหายไปหรือไม่ได้ใช้
- ขั้นตอนที่มีลูปหลายครั้ง : บ่งบอกถึงลำดับ JOIN หรือการซ้อนที่ไม่มีประสิทธิภาพ
- ช่องว่างใหญ่ระหว่างแถวและแถวจริง : แสดงถึงสถิติที่ไม่แม่นยำหรือการเข้าถึงข้อมูลมากเกินไป
ใช้ข้อมูลเชิงลึกเหล่านี้เป็นพื้นฐานสำหรับเทคนิค “การปรับแต่งคิวรี” ที่แนะนำในส่วนต่อไป.
5. ตัวอย่างการปรับแต่งคิวรีเชิงปฏิบัติ
การปรับแต่งคิวรีคืออะไร?
การปรับแต่งคิวรีหมายถึงการตรวจสอบและปรับปรุงคำสั่ง SQL เพื่อให้ทำงานได้อย่างมีประสิทธิภาพมากขึ้น โดยอิงจากวิธีที่ MySQL ประมวลผลคิวรีภายใน (แผนการดำเนินการ) คุณจะนำการปรับปรุงเช่น การเพิ่มดัชนี, การปรับลำดับการเชื่อม, และการกำจัดการประมวลผลที่ไม่จำเป็น ไปใช้.
ที่นี่ เราจะแสดงวิธีการปรับปรุงคิวรีโดยใช้ EXPLAIN ANALYZE พร้อมตัวอย่างที่เป็นรูปธรรม.
ตัวอย่างที่ 1: การปรับปรุงความเร็วด้วยดัชนี
ก่อนการปรับแต่ง
SELECT * FROM users WHERE email = 'example@example.com';
แผนการดำเนินการ (ส่วนย่อย)
-> Table scan on users (cost=10.5 rows=100000) (actual time=0.001..0.230 rows=1 loops=1)
ปัญหา
- ผลลัพธ์แสดง
Table scanหมายถึงการสแกนตารางเต็ม ซึ่งกับชุดข้อมูลขนาดใหญ่จะทำให้เกิดความล่าช้าสำคัญ
วิธีแก้: เพิ่มดัชนี
CREATE INDEX idx_email ON users(email);
แผนการดำเนินการหลังการปรับแต่ง
-> Index lookup on users using idx_email (cost=0.1 rows=1) (actual time=0.001..0.002 rows=1 loops=1)
ผลลัพธ์
- เวลาการดำเนินการลดลงอย่างมีนัยสำคัญ.
- การสแกนตารางเต็มถูกหลีกเลี่ยงโดยใช้ดัชนี.

ตัวอย่างที่ 2: การปรับลำดับการเชื่อม
ก่อนการปรับแต่ง
SELECT * FROM orders
JOIN users ON orders.user_id = users.id
WHERE users.age > 30;
แผนการดำเนินการ (ส่วนย่อย)
-> Nested loop join
-> Table scan on orders
-> Table scan on users
ปัญหา
- ทั้งสองตารางถูกสแกนเต็มที่ ส่งผลให้ค่าใช้จ่ายการเชื่อมสูง
วิธีแก้
- เพิ่มดัชนีบน
users.ageและกรองก่อนเพื่อลดขนาดเป้าหมายการเชื่อม.CREATE INDEX idx_age ON users(age);
แผนการดำเนินการหลังการปรับแต่ง
-> Nested loop join
-> Index range scan on users using idx_age
-> Index lookup on orders using idx_user_id
ผลลัพธ์
- เป้าหมายการเชื่อมถูกกรองก่อน ลดภาระการประมวลผลโดยรวม.
ตัวอย่างที่ 3: การแก้ไข Subquery
ก่อนการปรับแต่ง
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE total > 1000);
ปัญหา
- Subquery อาจถูกประเมินซ้ำหลายครั้ง ทำให้ประสิทธิภาพลดลง
วิธีแก้: เขียนใหม่เป็น JOIN
SELECT DISTINCT users.*
FROM users
JOIN orders ON users.id = orders.user_id
WHERE orders.total > 1000;
ผลลัพธ์
- แผนการดำเนินการได้รับการปรับให้เหมาะกับการประมวลผลแบบ JOIN และดัชนีมีแนวโน้มที่จะถูกใช้มากขึ้น.
ความสำคัญของการเปรียบเทียบก่อน/หลัง
Using EXPLAIN ANALYZE, you can verify optimization results with actual measured values. By comparing execution time and row counts before and after improvements, you ensure that tuning efforts are based on real performance gains rather than assumptions.
Important Considerations in Optimization
- Adding too many indexes can be counterproductive (slower INSERT/UPDATE performance).
การเพิ่มดัชนีมากเกินไปอาจทำให้ผลลัพธ์ตรงกันข้าม (ทำให้การ INSERT/UPDATE ช้าลง). - Execution plans depend on data volume and statistics, so validation is required per environment.
แผนการดำเนินการขึ้นอยู่กับปริมาณข้อมูลและสถิติ ดังนั้นต้องทำการตรวจสอบในแต่ละสภาพแวดล้อม. - One optimization rarely solves everything. Bottleneck analysis comes first.
การปรับแต่งเพียงอย่างเดียวมักไม่สามารถแก้ไขทุกอย่างได้ การวิเคราะห์คอขวดเป็นสิ่งแรกที่ต้องทำ.
6. Precautions and Best Practices
Important Notes When Using EXPLAIN ANALYZE
Although EXPLAIN ANALYZE is extremely powerful, improper use can lead to misunderstandings or even operational risks. Keeping the following points in mind ensures safe and effective query analysis.
1. Avoid Running Carelessly in Production
Because EXPLAIN ANALYZE actually executes the query, mistakenly using it with modification statements (INSERT/UPDATE/DELETE) can change data.
- In general, only use it with
SELECTstatements.
โดยทั่วไปให้ใช้กับคำสั่งSELECTเท่านั้น. - Prefer running it in a staging or testing environment rather than production.
ควรรันในสภาพแวดล้อม staging หรือ testing แทนการผลิต.
2. Consider the Impact of Caching
MySQL may return results from cache if the same query is executed repeatedly. As a result, execution time reported by EXPLAIN ANALYZE may differ from real‑world behavior.
Countermeasures:
- Clear the cache before execution (
RESET QUERY CACHE;).
ล้างแคชก่อนการดำเนินการ (RESET QUERY CACHE;). - Run multiple times and evaluate based on average values.
รันหลายครั้งและประเมินจากค่าเฉลี่ย.
3. Keep Statistics Up to Date
MySQL builds execution plans based on table and index statistics. If statistics are outdated, both EXPLAIN and EXPLAIN ANALYZE may provide misleading information.
After large INSERT or DELETE operations, update statistics using ANALYZE TABLE.
หลังจากการทำ INSERT หรือ DELETE จำนวนมาก ควรอัปเดตสถิติด้วย ANALYZE TABLE.
ANALYZE TABLE users;
4. Indexes Are Not a Silver Bullet
While indexes often improve performance, too many indexes slow down write operations.
แม้ว่าดัชนีมักช่วยเพิ่มประสิทธิภาพ, ดัชนีมากเกินไปจะทำให้การเขียนข้อมูลช้าลง.
Choosing between composite indexes and single‑column indexes is also important. Design indexes carefully based on query patterns and usage frequency.
การเลือกใช้ ดัชนีแบบคอมโพสิตหรือดัชนีแบบคอลัมน์เดียว ก็สำคัญเช่นกัน ควรออกแบบดัชนีอย่างระมัดระวังตามรูปแบบคิวรีและความถี่ในการใช้งาน.
5. Do Not Judge Solely by Execution Time
Results from EXPLAIN ANALYZE reflect only the performance of a single query. In real applications, network latency or backend processing may be the actual bottleneck.
ผลลัพธ์จาก EXPLAIN ANALYZE แสดงเพียงประสิทธิภาพของคิวรีเดียว ในแอปพลิเคชันจริง ความหน่วงของเครือข่ายหรือการประมวลผลด้านหลังอาจเป็นคอขวดที่แท้จริง.
Therefore, analyze queries within the context of the entire system architecture.
ดังนั้น, ควรวิเคราะห์คิวรีในบริบทของสถาปัตยกรรมระบบทั้งหมด.
Best Practices Summary
| Key Point | Recommended Action |
|---|---|
| Production safety | Use only with SELECT statements; avoid modification queries |
| Cache handling | Clear cache before testing; use averaged measurements |
| Statistics maintenance | Regularly update statistics with ANALYZE TABLE |
| Balanced index design | Minimize unnecessary indexes; consider read/write balance |
| Avoid tunnel vision | Optimize within the context of the entire application |
7. Frequently Asked Questions (FAQ)
Q1. From which version is EXPLAIN ANALYZE available?
A.
MySQL’s EXPLAIN ANALYZE was introduced in version 8.0.18 and later. It is not supported in versions prior to 8.0, so you should verify your MySQL version before using it.
EXPLAIN ANALYZE ของ MySQL ถูกนำมาใช้ตั้งแต่ เวอร์ชัน 8.0.18 ขึ้นไป ไม่รองรับในเวอร์ชันก่อน 8.0 ดังนั้นคุณควรตรวจสอบเวอร์ชัน MySQL ของคุณก่อนใช้งาน.
Q2. Can running EXPLAIN ANALYZE modify data?
A.
EXPLAIN ANALYZE executes the query internally.
When used with a SELECT statement, it does not modify data.
EXPLAIN ANALYZE ดำเนินการคิวรีภายใน.
เมื่อใช้กับคำสั่ง SELECT มันจะไม่แก้ไขข้อมูล.
Therefore, when used with a SELECT statement, it does not modify data.
ดังนั้น, เมื่อใช้กับคำสั่ง SELECT มันจะไม่แก้ไขข้อมูล.
However, if you mistakenly use it with INSERT, UPDATE, or DELETE, the data will be modified just as with a normal query.
อย่างไรก็ตาม หากคุณใช้โดยผิดพลาดกับ INSERT, UPDATE หรือ DELETE ข้อมูลจะถูกแก้ไขเช่นเดียวกับคิวรีปกติ.
For safety, it is recommended to run analyses in a test or staging database rather than in production.
เพื่อความปลอดภัย แนะนำให้ รันการวิเคราะห์ในฐานข้อมูลทดสอบหรือ staging แทนการผลิต.
Q3. Isn’t EXPLAIN alone sufficient?
A.
EXPLAIN is sufficient for reviewing the “estimated” execution plan. However, it does not provide measured values such as actual execution time or actual row counts.
EXPLAIN เพียงพอสำหรับการตรวจสอบ “แผนการดำเนินการที่คาดการณ์” อย่างไรก็ตาม มันไม่ให้ค่าที่วัดได้เช่น เวลาในการดำเนินการจริงหรือจำนวนแถวจริง.
If you need serious query tuning or want to verify optimization effects, EXPLAIN ANALYZE is more useful.
หากคุณต้องการการปรับแต่งคิวรีอย่างจริงจังหรืออยากตรวจสอบผลของการปรับแต่ง EXPLAIN ANALYZE จะมีประโยชน์มากกว่า.
Q4. How accurate are values like “loops” and “actual time”?
A.
Values such as actual time and loops are real execution metrics measured internally by MySQL. However, they may fluctuate slightly depending on OS conditions, cache state, and server load.
ค่าต่าง ๆ เช่น actual time และ loops เป็น เมตริกการดำเนินการจริงที่ MySQL วัดภายใน อย่างไรก็ตาม ค่าดังกล่าวอาจมีการเปลี่ยนแปลงเล็กน้อยขึ้นอยู่กับสภาพแวดล้อมของ OS, สถานะแคช, และภาระของเซิร์ฟเวอร์.
For this reason, do not rely on a single measurement. Instead, run the query multiple times and evaluate trends.
Q5. “cost” หมายถึงอะไรอย่างแท้จริง?
A.
cost คือค่าที่ประมาณโดยโมเดลต้นทุนภายในของ MySQL มันสะท้อนการประเมิน เชิงสัมพัทธ์ของต้นทุน CPU และ I/O ไม่ได้แสดงเป็นวินาที.
For example, if you see (cost=0.3) and (cost=2.5), the latter is estimated to be more expensive in relative terms.
Q6. ประโยชน์ของการใช้รูปแบบ JSON หรือ TREE คืออะไร?
A.
- รูปแบบ JSON : ผลลัพธ์ที่มีโครงสร้างง่ายต่อการแยกวิเคราะห์โดยโปรแกรม มีประโยชน์สำหรับเครื่องมืออัตโนมัติและแดชบอร์ด.
- รูปแบบ TREE : ทำให้การไหลของการดำเนินการและการซ้อนกันชัดเจนในเชิงภาพ เหมาะสำหรับการทำความเข้าใจคิวรีที่ซับซ้อนและลำดับการ JOIN.
Choose the format that best fits your purpose.
Q7. ควรทำอย่างไรหากไม่สามารถปรับปรุงประสิทธิภาพได้หลังจากตรวจสอบแผนการดำเนินการ?
A.
Consider additional approaches such as:
- ออกแบบดัชนีใหม่ (ดัชนีแบบคอมโพสิตหรือดัชนีครอบคลุม)
- เขียนคิวรีใหม่ (subqueries → JOINs, ลบคอลัมน์ SELECT ที่ไม่จำเป็น)
- ใช้วิวหรือเทเบิลชั่วคราว
- ตรวจสอบการตั้งค่า MySQL (ขนาดบัฟเฟอร์, การจัดสรรหน่วยความจำ ฯลฯ)
Performance tuning rarely succeeds with a single technique. A comprehensive and iterative approach is essential.


