FiveM MySQL Index คืออะไร? วิธีใช้ EXPLAIN หา Query Scan หนักและออกแบบ Index ให้ Database เร็วขึ้น
FiveM MySQL Index คือ Index ของฐานข้อมูล MySQL/MariaDB ที่ช่วยให้ Database สามารถค้นหา Rows ที่ต้องการได้มีประสิทธิภาพขึ้นใน Query ที่เหมาะสม แทนที่จะต้องไล่อ่านข้อมูลจำนวนมากโดยไม่จำเป็น โดยเฉพาะ FiveM Server ที่มี Tables อย่าง Characters, Vehicles, Users, Logs หรือ Settings ซึ่งมีข้อมูลเพิ่มขึ้นเรื่อยๆ ตามจำนวนผู้เล่น
MariaDB มี Index หลายประเภท เช่น Primary Key, Unique Index และ Regular Index และมี EXPLAIN สำหรับดูว่า Database วางแผน Execute SELECT, UPDATE หรือ DELETE อย่างไร.
สำหรับ FiveM จุดสำคัญคือ อย่าสร้าง Index แบบเดา เพราะ Index ที่มากเกินไปมีต้นทุนตอน INSERT และการแก้ข้อมูล MariaDB เองระบุว่า Index ทุกตัวต้องได้รับการ Update เมื่อข้อมูลเปลี่ยน และ Index ที่ซ้ำซ้อนอาจไม่จำเป็น.
แนวทางที่ถูกต้องคือ:
Slow Query
↓
ดู Query จริง
↓
EXPLAIN
↓
ดู WHERE / JOIN / ORDER BY
↓
ตรวจ Index ปัจจุบัน
↓
ออกแบบ Index
↓
วัดใหม่
① Database Index คืออะไร
ลองนึกภาพ Table:
vehicles
1
2
3
4
5
...
500,000
ถ้าต้องหา:
owner = license:abc123
Database ต้องมีวิธีค้นหา Record ที่ตรงเงื่อนไข
Index เป็นโครงสร้างที่ Database Optimizer สามารถใช้เพื่อเข้าถึงข้อมูลได้มีประสิทธิภาพขึ้นใน Query Pattern ที่เหมาะสม.
② ไม่มี Index แปลว่า Query ช้าเสมอไหม
ไม่เสมอไป
Table ขนาดเล็กอาจใช้เวลาเพียงเล็กน้อยแม้ไม่มี Secondary Index
ปัญหามักชัดขึ้นเมื่อ:
Rows เพิ่ม
+
Query ถูกเรียกบ่อย
+
Filter Column ไม่มี Index ที่เหมาะสม
ดังนั้นต้องดู Execution Plan จริงด้วย EXPLAIN ไม่ควรตัดสินจากจำนวน Rows เพียงอย่างเดียว.
③ FiveM Table ไหนมักต้องคิดเรื่อง Index
ตัวอย่างเชิง Architecture:
users
characters
vehicles
player_settings
logs
transactions
sessions
โดยเฉพาะ Columns ที่ปรากฏใน:
WHERE
JOIN
ORDER BY
บ่อยๆ ควรถูกนำมาวิเคราะห์ว่า Index เหมาะสมหรือไม่
แต่ไม่ได้หมายความว่า Columns เหล่านี้ต้องมี Index ทุกตัว
④ Primary Key คือ Index หรือไม่
ใช่
MariaDB จัด Primary Key เป็น Index ประเภทหนึ่ง และ Primary Key ใช้กำหนด Row Identity หลักของ Table.
ตัวอย่าง:
CREATE TABLE `characters` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`identifier` VARCHAR(64) NOT NULL,
`firstname` VARCHAR(50) NOT NULL,
`lastname` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
);
⑤ UNIQUE INDEX คืออะไร
Unique Index ใช้บังคับไม่ให้ค่าหรือชุดค่าที่อยู่ภายใต้ Index ซ้ำกันตามข้อกำหนดของ Database
MariaDB แยก Unique Index ออกจาก Regular Index และ Primary Key ใน Index Guide.
ตัวอย่าง:
CREATE UNIQUE INDEX `uq_users_identifier`
ON `users` (`identifier`);
เหมาะเมื่อ Business Rule ระบุว่า Identifier นั้นต้องไม่ซ้ำ
⑥ Regular Index คืออะไร
Regular Index ใช้ช่วยการค้นหาโดยไม่ได้บังคับค่าต้อง Unique
ตัวอย่าง:
CREATE INDEX `idx_vehicles_owner`
ON `vehicles` (`owner`);
MariaDB รองรับการเพิ่ม Index ผ่าน CREATE INDEX.
⑦ FiveM Vehicle Table ตัวอย่าง
สมมติ:
CREATE TABLE `vehicles` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`owner` VARCHAR(64) NOT NULL,
`model` VARCHAR(60) NOT NULL,
`stored` TINYINT NOT NULL DEFAULT 1,
`garage_id` INT NULL,
`created_at` DATETIME NOT NULL,
PRIMARY KEY (`id`)
);
แล้ว Resource ใช้:
SELECT
`id`,
`model`,
`stored`
FROM `vehicles`
WHERE `owner` = ?;
ถ้า owner เป็น Column ที่ Query นี้ใช้ตลอด ก็ควรนำมาวิเคราะห์เรื่อง Index
⑧ วิธีสร้าง Index ให้ owner
CREATE INDEX `idx_vehicles_owner`
ON `vehicles` (`owner`);
แต่ก่อนเพิ่มใน Production ควรตรวจว่า:
Index นี้มีอยู่แล้วหรือไม่
มี Composite Index ที่ขึ้นต้นด้วย owner หรือไม่
Query ใช้งานจริงอย่างไร
เพราะ MariaDB ระบุว่า INDEX(a,b) สามารถรองรับการค้นหาบางแบบที่ INDEX(a) รองรับได้ จึงอาจไม่จำเป็นต้องเก็บ Index ซ้ำทั้งสองชุด.
⑨ ดู Index ที่มีอยู่ยังไง
MariaDB รองรับ Index Metadata ผ่านคำสั่งในกลุ่ม Index Management และ Guide ครอบคลุม SHOW INDEX สำหรับตรวจ Index ของ Table.
ตัวอย่าง:
SHOW INDEX
FROM `vehicles`;
ก่อนสร้าง Index ใหม่ควรเปิดดูรายการนี้ก่อนเสมอ
⑩ EXPLAIN คืออะไร
EXPLAIN เป็นคำสั่งของ MariaDB สำหรับดูข้อมูลว่า Database วางแผน Execute Query อย่างไร
ปัจจุบันใช้กับ:
SELECT
UPDATE
DELETE
ได้.
ตัวอย่าง:
EXPLAIN
SELECT
`id`,
`model`
FROM `vehicles`
WHERE `owner` = 'license:example';
⑪ ทำไม EXPLAIN สำคัญกว่าเดา
เพราะ Developer อาจคิดว่า:
ฉันสร้าง Index แล้ว
=
Database ใช้มันแน่นอน
แต่ Optimizer เป็นผู้เลือก Execution Plan
จึงต้องตรวจว่า Query Plan แสดงอะไรจริง ไม่ใช่ตัดสินจาก Schema อย่างเดียว.
⑫ EXPLAIN ควรใช้กับ Query จริง
ถ้า Resource มี Query:
SELECT
`id`,
`model`,
`stored`
FROM `vehicles`
WHERE `owner` = ?
AND `stored` = ?
ORDER BY `id` DESC;
เวลาวิเคราะห์ควรใช้ Query Structure เดียวกัน
ไม่ใช่ทดสอบเพียง:
SELECT *
FROM `vehicles`;
เพราะ Execution Plan แตกต่างกัน
⑬ EXPLAIN ดูอะไรเป็นหลัก
สำหรับ Developer FiveM มือใหม่ ให้เริ่มจากดูแนวคิดเหล่านี้:
Table ไหนถูกอ่าน
↓
Index Candidate มีอะไร
↓
Database เลือก Index ไหน
↓
ต้องอ่าน Rows มากแค่ไหน
↓
มี Operations เพิ่มเติมหรือไม่
MariaDB EXPLAIN ให้ข้อมูลเกี่ยวกับ Execution Plan ที่ Optimizer เลือกใช้.
⑭ type ใน EXPLAIN คืออะไร
EXPLAIN Result มีข้อมูลเกี่ยวกับวิธีที่ Database เข้าถึง Table
ไม่ควรจำเพียงว่า:
ALL = แย่เสมอ
เพราะ Table ขนาดเล็กหรือ Query บางประเภท Optimizer อาจเลือก Full Scan อย่างสมเหตุสมผล
ต้องพิจารณาร่วมกับจำนวน Rows และ Query Context
⑮ possible_keys คืออะไร
ใน Execution Plan สามารถมีข้อมูลเกี่ยวกับ Index ที่เป็น Candidate สำหรับ Query
ถ้า Query:
WHERE `owner` = ?
แต่ไม่มี Index ที่เกี่ยวข้องเลย นั่นเป็นสัญญาณให้ตรวจ Schema ต่อ
อย่างไรก็ตามการมี Candidate ไม่ได้หมายความว่า Optimizer จะเลือกใช้จริง
⑯ key คืออะไร
แนวคิดคือ Index ที่ Execution Plan เลือกใช้จริงสำหรับขั้นตอนนั้น
ถ้า Developerคาดหวัง:
idx_vehicles_owner
แต่ Plan ไม่เลือก อาจต้องตรวจ:
Query Pattern
Column Selectivity
Table Size
Index Statistics
Composite Index
Data Distribution
แทนการ Force แบบสุ่ม
⑰ rows สำคัญอย่างไร
ค่า Estimate เกี่ยวกับจำนวน Rows ที่ต้องตรวจช่วยให้เห็นว่า Query อาจต้องอ่านข้อมูลมากแค่ไหน
หาก Table ใหญ่มากและ Query ต้องตรวจ Records จำนวนมาก นั่นเป็นจุดที่ควรวิเคราะห์ Index หรือ Query Structure เพิ่ม
⑱ Full Table Scan คืออะไร
แนวคิด:
ต้องหา Owner คนเดียว
แต่ Database
↓
อ่าน Table จำนวนมาก
↓
ตรวจ Row ทีละส่วน
อาจเกิดขึ้นหากไม่มี Index ที่เหมาะสมหรือ Optimizerเห็นว่า Scan Table คุ้มกว่า
อย่าด่วนสรุปว่า Full Scan ทุกครั้งคือ Bug ต้องดู Table และ Workload จริง
⑲ Index ช่วย WHERE อย่างไร
ตัวอย่าง Query:
SELECT
`id`,
`model`
FROM `vehicles`
WHERE `owner` = ?;
Index:
CREATE INDEX `idx_vehicles_owner`
ON `vehicles` (`owner`);
สามารถเป็น Candidate ให้ Optimizer ใช้ค้นหาตาม owner โดยตรงตาม Index Design.
⑳ Composite Index คืออะไร
Composite หรือ Compound Index คือ Index ที่มีมากกว่าหนึ่ง Column
MariaDB ยกตัวอย่างลักษณะ:
INDEX(last_name, first_name)
เป็น Composite Index.
FiveM ตัวอย่าง:
CREATE INDEX `idx_vehicles_owner_stored`
ON `vehicles` (`owner`, `stored`);
㉑ Composite Index เหมาะกับ Query แบบไหน
สมมติ Resource ใช้:
SELECT
`id`,
`model`
FROM `vehicles`
WHERE `owner` = ?
AND `stored` = ?;
Composite Index:
(owner, stored)
อาจเหมาะกว่า Single-column Index บางแบบ
แต่ต้องตรวจด้วย EXPLAIN และ Data Distribution จริง.
㉒ Column Order สำคัญไหม
สำคัญ
Composite Index:
INDEX(owner, stored)
และ:
INDEX(stored, owner)
ไม่ควรถูกมองว่าเหมือนกันทุกกรณี
MariaDB อธิบาย Composite Index ผ่านลำดับ Columns และการเดิน B-tree ของ Index โดยตรง.
㉓ Leftmost Prefix แนวคิดคืออะไร
ถ้ามี:
INDEX(owner, stored)
Query ที่ Filter ตาม owner สามารถได้รับประโยชน์จากส่วนเริ่มต้นของ Composite Index ในหลายกรณี
MariaDB ระบุว่า INDEX(a,b) สามารถค้นหาสิ่งที่ INDEX(a) ทำได้ในบริบทการออกแบบ Index ที่เหมาะสม.
ดังนั้นการมี:
INDEX(owner)
INDEX(owner, stored)
พร้อมกันอาจซ้ำซ้อน
㉔ Index ซ้ำซ้อนคืออะไร
ตัวอย่าง:
INDEX(owner)
INDEX(owner, stored)
MariaDB ระบุว่าหากมี INDEX(a,b) ก็ไม่จำเป็นต้องมี INDEX(a) แยกเสมอไป เพราะ Index ที่ยาวกว่าสามารถรองรับ Prefix นั้นได้.
ก่อนลบ Index ต้องตรวจ Queries ทั้งระบบก่อน
㉕ ทำไม Index เยอะเกินไปไม่ดี
เพราะ Index ไม่ได้มี Cost เฉพาะตอน Read
เมื่อมี:
INSERT
UPDATE
DELETE
Database ต้องรักษา Index ที่เกี่ยวข้องด้วย
MariaDB เตือนว่า Index มากขึ้นหมายถึง INSERT ช้าลง และให้ Rule of Thumb เกี่ยวกับการจำกัดจำนวน Index ที่ไม่จำเป็น.
㉖ อย่า Index ทุก Column
ตัวอย่าง Table:
id
owner
model
stored
garage_id
color
label
created_at
updated_at
การทำ:
INDEX(owner)
INDEX(model)
INDEX(stored)
INDEX(garage_id)
INDEX(color)
INDEX(label)
INDEX(created_at)
INDEX(updated_at)
โดยไม่ดู Query จริงอาจสร้าง Index จำนวนมากที่แทบไม่ได้ใช้
ให้เริ่มจาก Query Pattern
㉗ Query Pattern คืออะไร
คือรูปแบบ Queries ที่ Resource ใช้งานจริง
เช่น Garage Resource อาจมี:
WHERE owner = ?
และ:
WHERE owner = ?
AND stored = ?
และ:
WHERE garage_id = ?
AND stored = ?
Index Design จึงต้องดู Queries ทั้งชุด ไม่ใช่ Query เดียว
㉘ Covering Index คืออะไร
MariaDB อธิบายว่า Covering Index คือ Index ที่มี Columns ที่ SELECT ต้องการครบ ทำให้ Query บางประเภทสามารถอ่านข้อมูลจาก Index B-tree ได้โดยไม่ต้องย้อนกลับไปอ่าน Row Data เพิ่ม.
ตัวอย่างเชิงแนวคิด:
SELECT
`owner`,
`stored`
FROM `vehicles`
WHERE `owner` = ?;
Index:
(owner, stored)
อาจทำหน้าที่เป็น Covering Index สำหรับ Query ที่เหมาะสม
㉙ ต้องทำ Covering Index ทุก Query ไหม
ไม่
MariaDB เตือนเรื่อง Index จำนวนมากและต้นทุนต่อ Writes เช่นกัน.
ดังนั้นไม่ควรสร้าง Index ใหญ่เพื่อ Cover ทุก SELECT โดยอัตโนมัติ
ควรใช้กับ Query ที่:
เรียกบ่อย
+
มี Performance Impact
+
วัดแล้วคุ้ม
㉚ ORDER BY เกี่ยวกับ Index ไหม
เกี่ยวข้องได้
ตัวอย่าง:
SELECT
`id`,
`message`,
`created_at`
FROM `logs`
WHERE `identifier` = ?
ORDER BY `created_at` DESC
LIMIT 50;
อาจต้องพิจารณา Index ที่สัมพันธ์กับทั้ง Filtering และ Ordering
แต่ต้องใช้ EXPLAIN ตรวจ Execution Plan ก่อนตัดสินใจ.
㉛ ตัวอย่าง Composite Index สำหรับ Logs
สมมติ Query ใช้ตลอด:
WHERE `identifier` = ?
ORDER BY `created_at` DESC
อาจทดลอง Index:
CREATE INDEX `idx_logs_identifier_created`
ON `logs` (`identifier`, `created_at`);
จากนั้น:
EXPLAIN
SELECT
`id`,
`message`,
`created_at`
FROM `logs`
WHERE `identifier` = 'license:example'
ORDER BY `created_at` DESC
LIMIT 50;
แล้วเปรียบเทียบ Plan ก่อน/หลัง
㉜ JOIN เกี่ยวกับ Index อย่างไร
สมมติ:
SELECT
c.`firstname`,
v.`model`
FROM `characters` c
JOIN `vehicles` v
ON v.`character_id` = c.`id`
WHERE c.`identifier` = ?;
Columns ที่ใช้ Join และ Filter เป็น Candidate สำคัญในการวิเคราะห์ Index
แต่ยังต้องดู Execution Plan จริงด้วย
㉝ Foreign Key มี Index หรือไม่
MariaDB ระบุว่า Foreign Key ต้องมี Index ที่เหมาะสม และถ้าไม่มี Index ที่รองรับ Foreign Key MariaDB สามารถสร้าง Index ให้โดยอัตโนมัติในบางกรณี.
ดังนั้นก่อนสร้าง Index บน Foreign Key Column ซ้ำ ให้ตรวจ Existing Indexes ก่อน
㉞ LIKE '%keyword%' ใช้ Index ธรรมดาได้ดีไหม
Query ที่ค้นหา Text แบบมี Wildcard นำหน้ามี Characteristics ต่างจาก Equality Lookup
ถ้าต้องค้นหาข้อความเต็มรูปแบบจำนวนมาก MariaDB มี FULLTEXT Index และ MATCH() ... AGAINST() สำหรับ Full-text Search โดยเฉพาะ.
อย่าพยายามแก้ Search ทุกประเภทด้วย Regular Index อย่างเดียว
㉟ FULLTEXT Index คืออะไร
MariaDB มี FULLTEXT Index สำหรับการค้นหาข้อความภายใน Text Fields โดยรองรับ Full-text Search Modes หลายแบบ.
อย่างไรก็ตาม FiveM Resource ส่วนใหญ่ไม่ได้ต้องใช้ Full-text Index เว้นแต่มีระบบ Search เช่น:
Admin Logs Search
Message Search
Large Text Records
㊱ Index Statistics คืออะไร
MariaDB Optimizer ใช้ Index Statistics เป็นข้อมูลช่วยเลือก Execution Plan
MariaDB ระบุว่า Index Statistics มีความสำคัญต่อการตัดสินใจของ Query Optimizer.
ถ้า Statistics ไม่สะท้อนข้อมูลปัจจุบัน Optimizer อาจเลือก Plan ที่ไม่เหมาะกับ Distribution ใหม่ได้
㊲ ANALYZE TABLE คืออะไร
MariaDB มี:
ANALYZE TABLE `vehicles`;
สำหรับวิเคราะห์และจัดเก็บ Key Distribution/Statistics ที่ Optimizer ใช้ในการเลือก Execution Plan.
ไม่ใช่คำสั่งที่ต้อง Run ทุก Query
ใช้เมื่อมีเหตุผลด้าน Statistics และ Database Maintenance
㊳ เพิ่ม Index แล้ว EXPLAIN ยังไม่ใช้เพราะอะไร
สาเหตุที่เป็นไปได้ เช่น:
Table เล็ก
Index Selectivity ต่ำ
Statistics
Query Structure
Data Distribution
มี Index อื่นเหมาะกว่า
Optimizer เป็นผู้ตัดสิน Plan
จึงไม่ควรบังคับว่า Index ต้องถูกใช้เพียงเพราะเราเพิ่งสร้างมัน
㊴ Selectivity คืออะไร
แนวคิดง่ายๆ คือ Column สามารถแบ่ง Rows ออกจากกันได้มากแค่ไหน
ตัวอย่าง:
owner
= มีค่าหลากหลายมาก
stored
= มีเพียง 0 / 1
ในหลาย Dataset owner มีความเฉพาะเจาะจงมากกว่า stored
นี่เป็นหนึ่งในเหตุผลที่ Column Order ของ Composite Index ต้องอิงข้อมูลจริง ไม่ใช่ชื่อ Column
㊵ Index บน Boolean Column ดีไหม
ไม่สามารถตอบว่า “ดีเสมอ” หรือ “ไม่ดีเสมอ”
ตัวอย่าง:
stored = 0 / 1
มี Cardinality ต่ำ
Index เดี่ยวบน Column นี้อาจไม่คุ้มในหลาย Workload แต่:
INDEX(owner, stored)
อาจมีประโยชน์กับ Query ที่ Filter Owner ก่อนแล้วตามด้วย Stored
ต้องดู Query และ EXPLAIN
㊶ Query Garage ตัวอย่างก่อน Optimize
SELECT
`id`,
`model`,
`stored`
FROM `vehicles`
WHERE `owner` = ?
AND `stored` = ?
ORDER BY `id` DESC;
ก่อนเพิ่ม Index:
EXPLAIN
SELECT
`id`,
`model`,
`stored`
FROM `vehicles`
WHERE `owner` = 'license:example'
AND `stored` = 1
ORDER BY `id` DESC;
เก็บ Baseline ก่อน
㊷ เพิ่ม Composite Index
CREATE INDEX `idx_vehicles_owner_stored`
ON `vehicles` (`owner`, `stored`);
MariaDB รองรับ Composite Index และ CREATE INDEX อย่างเป็นทางการ.
จากนั้น Run EXPLAIN ใหม่
㊸ อย่าดูแค่ EXPLAIN ต้องวัด Query Time ด้วย
Execution Plan สำคัญ แต่เป้าหมายสุดท้ายคือ Performance ของ Workload จริง
สำหรับ FiveM ที่ใช้ oxmysql สามารถดู Query Speeds ผ่าน Debug UI หรือ Server Console เมื่อเปิด mysql_debug; oxmysql ระบุว่าความเร็วจริงขึ้นกับ Hardware, Database Settings, Version และ Current Workload.
ดังนั้นใช้:
EXPLAIN
+
Query Timing
ร่วมกัน
㊹ mysql_debug ใช้ร่วมกับ Index Optimization อย่างไร
Workflow:
mysql_debug
↓
เจอ Query ช้า
EXPLAIN
↓
ดู Plan
Index
↓
แก้ Schema
mysql_debug
↓
วัดใหม่
oxmysql ระบุว่า Query Speed จริงสามารถดูจาก Debug UI และ Console เมื่อ mysql_debug เปิด.
㊺ FiveM Profiler ยังจำเป็นไหม
จำเป็นเมื่อไม่แน่ใจว่าปัญหาอยู่:
Database
หรือ
Resource Code
Cfx.re Profiler ใช้หา Server Hitch ผ่าน CPU Time Spikes และสามารถเจาะ Resource/Thread ที่ใช้เวลามากได้.
และ Cfx.re ระบุว่า SQL Query ที่ทำงานช้าสามารถเป็นหนึ่งในสาเหตุ Hitch Warning ได้.
㊻ Query เร็วแต่ Resource ยัง Hitch
สมมติ:
Database Query = 10 ms
Resource Tick = 300 ms
ปัญหาอาจอยู่ที่:
Loop Results
JSON Decode
Nested Loop
Entity Processing
Event Dispatch
ไม่ใช่ Index
Profiler จึงช่วยแยก Bottleneck
㊼ Query ช้าแต่ CPU Resource ไม่สูง
ก็ยังเป็นไปได้
Database Operation อาจต้องรอผลโดยไม่ได้สร้าง CPU Spike แบบเดียวกับ Heavy Loop
จึงต้องตรวจ:
oxmysql Timing
+
EXPLAIN
+
Database Monitoring
+
FiveM Profiler
ร่วมกัน
㊽ MySQL.prepare แทน Index ได้ไหม
ไม่ได้
oxmysql ระบุว่า MySQL.prepare เหมาะสำหรับ Queries ที่ถูกเรียกบ่อยและช่วยให้ Query Execution แบบเดิมซ้ำๆ เร็วขึ้น.
แต่ถ้า SQL ต้อง Scan Records จำนวนมหาศาลเพราะไม่มี Index ที่เหมาะสม การเปลี่ยน API เป็น prepare ไม่ได้แทน Query Optimization
㊾ Prepare + Index ใช้ร่วมกันได้ไหม
ได้
ตัวอย่าง:
local vehicles =
MySQL.prepare.await(
[[
SELECT
`id`,
`model`,
`stored`
FROM `vehicles`
WHERE `owner` = ?
AND `stored` = ?
]],
{
identifier,
1
}
)
และ Database มี:
CREATE INDEX `idx_vehicles_owner_stored`
ON `vehicles` (`owner`, `stored`);
แต่ต้องวัดว่าการใช้ Prepare มีประโยชน์จริงกับ Frequency ของ Query นั้น.
㊿ อย่าปรับ Query API ก่อนรู้ Bottleneck
คำถามที่ควรถามคือ:
Query ช้าเพราะอะไร?
① SQL Structure?
② Index?
③ Result ใหญ่?
④ ถูกเรียกบ่อย?
⑤ Database Load?
⑥ FiveM Resource Code?
แก้ตามต้นเหตุ
ไม่ใช่เปลี่ยน:
query
→ prepare
ทุกตัวแล้วหวังว่า Database จะเร็วขึ้นทั้งหมด
51. Index กับ SELECT * เกี่ยวข้องไหม
ถ้า Resource ต้องใช้เพียง 3 Columns:
SELECT
`id`,
`model`,
`stored`
FROM `vehicles`
WHERE `owner` = ?;
ชัดกว่า:
SELECT *
FROM `vehicles`
WHERE `owner` = ?;
นอกจากนี้การเลือก Columns ที่เหมาะสมยังเปิดโอกาสให้บาง Query ใช้ Covering Index ได้เมื่อ Index มีข้อมูลที่ต้องการครบ.
52. LIMIT ช่วย Index ไหม
LIMIT มีหน้าที่จำกัดจำนวน Rows ที่คืน ไม่ใช่สร้าง Index
ตัวอย่าง:
SELECT
`id`,
`message`,
`created_at`
FROM `logs`
WHERE `identifier` = ?
ORDER BY `created_at` DESC
LIMIT 50;
Index และ LIMIT สามารถทำงานร่วมกันใน Query Plan ที่เหมาะสม แต่ยังต้องตรวจ EXPLAIN
53. Pagination สำคัญกับ Logs Table
Table Logs สามารถโตมากตามเวลา
แทนที่จะ:
เปิด Admin UI
↓
โหลด Logs ทั้งหมด
ใช้:
50 Rows ต่อหน้า
จะลด Result Set ที่ Database และ Resource ต้องจัดการ
Index ที่สัมพันธ์กับ Filter/Order สามารถช่วย Query Pagination ได้ใน Design ที่เหมาะสม
54. OFFSET เยอะมี Cost ได้ไหม
Query รูปแบบ:
LIMIT 50 OFFSET 500000
อาจมี Performance Characteristics ที่ต่างจาก Page แรกมาก
สำหรับ Logs ขนาดใหญ่ อาจพิจารณา Keyset/Cursor Pagination เช่นอิง id หรือ Timestamp ตาม Architecture
แต่ต้องออกแบบกับ Query และ UX จริง
55. Index Primary Key ใช้ Pagination ได้อย่างไร
ถ้า Logs มี:
id
เป็น Primary Key
สามารถออกแบบ:
SELECT
`id`,
`message`
FROM `logs`
WHERE `id` < ?
ORDER BY `id` DESC
LIMIT 50;
สำหรับ Cursor Pagination ในบาง Use Case
Primary Key ถูก Index อยู่แล้วตาม Database Design.
56. Index กับ VARCHAR ยาวมากควรระวังอะไร
Columns ประเภท String ที่ใช้เป็น Index ต้องพิจารณา:
Data Length
Character Set
Selectivity
Query Pattern
อย่าเพิ่ม Index ลง Text Fields ทุกตัว
ถ้าค้น Full Text จริงควรพิจารณา FULLTEXT ตามประเภทข้อมูล.
57. FiveM Identifier ควร Index ไหม
ถ้า Table ใช้:
WHERE `identifier` = ?
อย่างต่อเนื่อง เช่นค้น Character หรือ User Record การมี Index ที่เหมาะสมบน Identifier เป็น Candidate ที่ควรวิเคราะห์
ตัวอย่าง:
CREATE INDEX `idx_characters_identifier`
ON `characters` (`identifier`);
แล้วตรวจด้วย EXPLAIN
58. Internal Character ID ยังสำคัญไหม
ควรมี Persistent Application ID เช่น:
character_id
เป็น Primary Key ของ Character
แทนการใช้ FiveM Runtime Server ID
ตัวอย่าง:
PRIMARY KEY (`id`)
ช่วยให้ Relations เช่น Vehicles, Settings หรือ Statistics อ้าง Character เดิมได้อย่างชัดเจน
59. Foreign Key กับ Character ID
ตัวอย่าง:
characters.id
↓
vehicles.character_id
Foreign Key สามารถใช้รักษา Referential Integrity ตาม Database Design และ MariaDB กำหนดเรื่อง Index ของ Foreign Key ไว้ด้วย.
อย่างไรก็ตาม Resources FiveM แต่ละชุดมี Schema Architecture ต่างกัน ควรดู Framework Compatibility ก่อนเพิ่ม Constraints ลง Production
60. SHOW INDEX_STATISTICS คืออะไร
MariaDB มี SHOW INDEX_STATISTICS สำหรับดู Statistics การใช้งาน Index เพื่อช่วยวิเคราะห์ว่า Index ใดถูกใช้งานบ่อย.
ตัวอย่าง:
SHOW INDEX_STATISTICS;
ความพร้อมใช้งานและ Configuration ของ Statistics ต้องตรวจตาม MariaDB Version/Environment ที่ใช้
61. Index ไม่เคยถูกใช้งานควรลบทันทีไหม
ไม่
อาจมี Query ที่:
ใช้เฉพาะ Maintenance
ใช้เดือนละครั้ง
ใช้ตอน Migration
ใช้ตอน Admin Action
และ Statistics Window อาจยังไม่ครอบคลุม
ก่อน Drop Index ต้องตรวจ:
Schema
Queries ทั้งระบบ
Framework
Migration Scripts
Production Workload
ให้ครบ
62. Ignored Index คืออะไร
MariaDB รองรับ Ignored Indexes ซึ่ง Index ยังถูกเก็บและ Maintain อยู่ แต่ Optimizer จะไม่ใช้ Index นั้นในการวาง Query Plan.
แนวคิดนี้มีประโยชน์ในงาน Database Tuning บางประเภทสำหรับทดสอบผลของการไม่ใช้ Index ก่อนตัดสินใจลบจริง
63. ANALYZE TABLE หลังข้อมูลเปลี่ยนมากช่วยอะไร
ANALYZE TABLE อัปเดต Key Distribution/Index Statistics ที่ Optimizer ใช้สำหรับเลือก Execution Plan.
หาก Data Distribution เปลี่ยนมากและ Plan ดูผิดปกติ นี่เป็นเครื่องมือหนึ่งที่ Database Administrator สามารถพิจารณาได้
ไม่ควร Run ต่อเนื่องทุกไม่กี่วินาที
64. ก่อน CREATE INDEX Production ควรทำอะไร
Checklist:
① Backup Database
② ตรวจ Table Size
③ ตรวจ Existing Indexes
④ จด Query Timing
⑤ Run EXPLAIN
⑥ ทดสอบ Index บน Staging
⑦ Run EXPLAIN ใหม่
⑧ วัด Query Timing ใหม่
⑨ ตรวจ Write Performance
⑩ ค่อยขึ้น Production
MariaDB ระบุว่า CREATE INDEX ถูก Map ไปเป็น ALTER TABLE Operation และบาง Index Changes สามารถเกี่ยวข้องกับการเปลี่ยนโครงสร้าง Table.
65. CREATE INDEX บน Table ใหญ่ควรระวัง
อย่ารัน DDL บน Production Table ขนาดใหญ่แบบสุ่มในช่วง Player เยอะ
เพราะ Index Creation เป็น Schema Operation และผลกระทบขึ้นกับ:
MariaDB Version
Storage Engine
Table Size
Operation
Server Resources
ควรทดสอบและมี Maintenance Plan
66. DROP INDEX ควรระวังเหมือนกัน
ก่อนลบ Index ต้องรู้ว่า Resource หรือ Query ใดพึ่ง Index นั้น
ทำ:
SHOW INDEX
↓
ตรวจ Queries
↓
EXPLAIN
↓
Benchmark
↓
Backup
ก่อน
Index ที่ดูซ้ำอาจยังมีความแตกต่างใน Query Pattern บางแบบ
67. Slow Query หลังเพิ่ม Index แต่ไม่ดีขึ้น
ตรวจ:
EXPLAIN ใช้ Index หรือไม่
↓
Result ใหญ่หรือไม่
↓
Query Count สูงหรือไม่
↓
Database CPU สูงหรือไม่
↓
Resource Process Result หนักหรือไม่
↓
Network Database Remote หรือไม่
อย่าซ้อน Index เพิ่มไปเรื่อยๆ
68. Slow Query หายแต่ INSERT ช้าลงเกิดจากอะไร
Index เพิ่มขึ้นทำให้ Write Operations ต้อง Maintain Index เพิ่ม
MariaDB เตือนว่า More Indexes สามารถทำให้ Inserts ช้าลง.
จึงต้องวัดทั้ง:
Read
และ
Write
ไม่ใช่ Optimize SELECT อย่างเดียว
69. Query ใช้ owner + stored + garage_id ต้องสร้าง Index 3 ตัวไหม
ไม่จำเป็น
สมมติ Queries:
WHERE owner = ?
AND stored = ?
AND garage_id = ?
อาจต้องวิเคราะห์ Composite Index
เช่น:
(owner, stored, garage_id)
แต่ Column Order และจำนวน Columns ต้องอิง Queries อื่นด้วย
MariaDB แนะนำสร้าง Index จาก SELECT Pattern จริงและเตือนเรื่อง Redundant/Excessive Indexes.
70. Index Design สำหรับ FiveM ควรเริ่มจากไหน
เริ่มจาก Resources ที่สร้าง Query มากที่สุด เช่น:
Character Load
Garage
Inventory Metadata
Admin Logs
Player Settings
แล้วเรียงตาม:
Query Frequency
×
Query Time
×
Player Count
Query 2 ms ที่เรียกหนึ่งล้านครั้งอาจสำคัญกว่า Query 100 ms ที่เรียกวันละครั้ง
71. oxmysql Debug ช่วยดู Query Count ได้ไหม
oxmysql Debug UI แสดงข้อมูล Query/Resource Statistics และ Benchmark Documentation ระบุว่าความเร็ว Query จริงดูได้จาก Debug UI หรือ Console เมื่อ mysql_debug ทำงาน.
จึงเหมาะกับการหา:
Resource ไหน Query เยอะ
Query ไหนช้า
ก่อนออกแบบ Index
72. FiveM Hitch Warning กับ Index
Cfx.re ระบุว่า Hitch Warning สามารถเกิดจาก SQL Queries ที่ใช้เวลานาน รวมถึง Unoptimized Loops.
ดังนั้น Index เป็นเพียงหนึ่งในเครื่องมือแก้ Database-side Bottleneck
หาก Profiler ชี้ว่า Resource ใช้ CPU กับ Loop มากกว่า SQL การเพิ่ม Index จะไม่แก้ Loop
73. วิธีทดสอบ Before/After Index
ก่อน:
Query = 180 ms
Rows = ...
Plan = ...
เพิ่ม Index
หลัง:
Query = 12 ms
Rows = ...
Plan = ...
ตัวเลขต้องมาจาก Server จริง ไม่ใช่ Copy จาก Tutorial
oxmysql ระบุว่า Performance แตกต่างตาม Hardware, Settings, Version และ Workload.
74. อย่า Benchmark ด้วย Database ว่างเปล่าอย่างเดียว
Query ที่มี:
100 Rows
อาจดูเร็วมาก
แต่ Production:
5,000,000 Rows
อาจต่างกันชัดเจน
ควร Test ด้วย Data Size/Distribution ใกล้ Production
75. SQL Injection เกี่ยวกับ Index ไหม
เป็นคนละเรื่อง
Index:
Performance
Parameterized Query:
Query Safety / Correct Parameter Handling
อย่าเปลี่ยนจาก Parameterized Query เป็น String Concatenation เพียงเพราะกำลัง Optimize SQL
76. Index ไม่แก้ Query ที่ถูกเรียกผิด Architecture
ตัวอย่าง:
ทุก Frame
↓
SELECT WHERE owner = ?
ต่อให้ Queryเร็วมาก การ Query Database ทุก Frame ก็ยังเป็น Architecture ที่ควรแก้
ควรพิจารณา:
Load Once
↓
Cache
↓
Update on Change
ตาม Use Case
77. Index ไม่แทน Cache
Database:
Persistent Source
Index:
ช่วย Database Lookup
Cache:
ลดการอ่าน Database ซ้ำ
ทั้งสามทำหน้าที่ต่างกัน
Resource ที่ออกแบบดีอาจใช้ทั้งสามอย่างร่วมกัน
78. Index ไม่แทน Pagination
ถ้า Queryคืน:
500,000 Rows
แม้ค้นหาได้เร็ว Resource ก็ยังต้อง:
ส่งข้อมูล
Allocate Memory
Loop Result
Serialize
Pagination หรือจำกัดข้อมูลที่คืนยังมีความสำคัญ
79. Index ไม่แทน Query Design
ตัวอย่างที่ควรตรวจ:
SELECT *
FROM giant_table;
การสร้าง Indexไม่ได้ช่วย Query ที่ต้องการทุก Row อย่างมหัศจรรย์
ต้องถามว่า Resource ต้องใช้ข้อมูลทั้งหมดจริงหรือไม่
80. ตัวอย่าง Complete Optimization Flow
เริ่มจาก oxmysql พบ:
garage query = slow
SQL:
SELECT
`id`,
`model`,
`stored`
FROM `vehicles`
WHERE `owner` = ?
AND `stored` = ?;
ทำ:
① mysql_debug
② ดู Timing
③ EXPLAIN
④ SHOW INDEX
⑤ ตรวจ Existing Index
⑥ เพิ่ม Composite Index ใน Test DB
⑦ EXPLAIN ใหม่
⑧ Benchmark
⑨ FiveM Profiler
⑩ Load Test
นี่เป็น Flow ที่ควรใช้มากกว่าการเพิ่ม Index ทันที
81. ตัวอย่าง Index สำหรับ Character Selection
Query:
SELECT
`id`,
`firstname`,
`lastname`
FROM `characters`
WHERE `identifier` = ?
ORDER BY `id`;
Candidate:
CREATE INDEX `idx_characters_identifier`
ON `characters` (`identifier`);
จากนั้นตรวจด้วย:
EXPLAIN
SELECT
`id`,
`firstname`,
`lastname`
FROM `characters`
WHERE `identifier` = 'license:example'
ORDER BY `id`;
82. ตัวอย่าง Index สำหรับ Player Settings
หากหนึ่ง Player มีเพียงหนึ่ง Settings Row และ Identifier ต้อง Unique:
CREATE UNIQUE INDEX `uq_settings_identifier`
ON `player_settings` (`identifier`);
Unique Index มีทั้งบทบาท Lookup และ Constraint ไม่ให้ค่าซ้ำตาม Database Definition.
83. ตัวอย่าง Index สำหรับ Logs
Query:
SELECT
`id`,
`event`,
`created_at`
FROM `logs`
WHERE `identifier` = ?
ORDER BY `created_at` DESC
LIMIT 100;
Candidate:
CREATE INDEX `idx_logs_identifier_created`
ON `logs` (`identifier`, `created_at`);
จากนั้นใช้ EXPLAIN และ Query Timing ยืนยัน
84. FiveM MySQL Index ทำ Server เร็วขึ้นแน่นอนไหม
ไม่สามารถรับประกันทุก Query
Index ช่วยเฉพาะ Query Pattern ที่ Optimizer สามารถใช้ Index นั้นได้อย่างเหมาะสม และ Index เองเพิ่มต้นทุนของ Write Operations.
ดังนั้นคำตอบที่ถูกต้องคือ:
Index ที่ออกแบบถูกกับ Query ที่ถูกต้องสามารถช่วยได้มาก แต่ Index ที่ผิดหรือเกินจำเป็นก็สร้าง Cost เพิ่มได้
Checklist FiveM MySQL Index
ก่อนเพิ่ม Index ตรวจ:
Query ไหนช้า
Resource ไหนเรียก
Query ถูกเรียกบ่อยแค่ไหน
Table มีกี่ Rows
Query คืนกี่ Rows
ใช้ WHERE อะไร
ใช้ JOIN อะไร
ใช้ ORDER BY อะไร
ใช้ LIMIT หรือไม่
มี Existing Index อะไร
มี Redundant Index หรือไม่
ใช้
SHOW INDEXใช้
EXPLAINดู Plan ก่อนเพิ่ม Index
เก็บ Query Timing Baseline
ตรวจ Single-column Index
ตรวจ Composite Index
ตรวจ Column Order
ตรวจ Selectivity
ตรวจ Foreign Key Index
ไม่ Index ทุก Column
ไม่สร้าง Covering Index ทุก Query
ระวัง Write Performance
ตรวจ INSERT Performance
ตรวจ UPDATE Performance
ตรวจ DELETE Performance
ใช้ mysql_debug
ใช้ oxmysql Debug UI เมื่อเหมาะสม
ใช้ FiveM Profiler
ตรวจ Server Hitch
ตรวจ Database CPU
ทดสอบด้วย Production-like Data
Backup ก่อน Schema Change
Test บน Staging
EXPLAIN หลังเพิ่ม Index
Benchmark หลังเพิ่ม Index
ตรวจ Query Count
แก้ N+1 Query
ลด SELECT *
ใช้ Pagination
Cache เมื่อเหมาะสม
ไม่ Query ทุก Frame
ใช้ Prepare เมื่อ Query ถูกเรียกบ่อยและเหมาะสม
ANALYZE TABLE เมื่อมีเหตุผลด้าน Statistics
อย่าลบ Index โดยไม่ตรวจ Workload
ตารางคำสั่ง Database Optimization ที่ควรรู้
| คำสั่ง | หน้าที่ |
|---|---|
SHOW INDEX FROM table | ดู Index ที่มี |
EXPLAIN SELECT ... | ดู Execution Plan |
CREATE INDEX | เพิ่ม Regular Index |
CREATE UNIQUE INDEX | เพิ่ม Unique Index |
ANALYZE TABLE | อัปเดต Statistics สำหรับ Optimizer |
SHOW INDEX_STATISTICS | ดู Index Usage Statistics ใน Environment ที่รองรับ |
mysql_debug | ดู oxmysql Query Timing |
| FiveM Profiler | หา Resource/Thread ที่ Hitch |
MariaDB มีเครื่องมือ Index, EXPLAIN, ANALYZE TABLE และ Index Statistics โดยตรง ส่วน oxmysql และ FiveM Profilerช่วยเชื่อม Database Performance กลับมาที่ Resource.
FiveM MySQL Index ช่วยอะไร
ช่วยให้ Database Optimizer มีโครงสร้างเพิ่มเติมสำหรับค้นหา Rows ตาม Query Pattern ที่เหมาะสม เช่น:
WHERE `owner` = ?
แทนการพึ่ง Table Scan ในทุกสถานการณ์
MariaDB มี Index Optimization Documentation โดยตรงสำหรับการออกแบบ Index ตาม Query.
FiveM Query ไม่มี Index แก้อย่างไร
อย่าเริ่มด้วย CREATE INDEX ทันที
ทำ:
Query จริง
↓
EXPLAIN
↓
SHOW INDEX
↓
วิเคราะห์ WHERE/JOIN/ORDER BY
↓
สร้าง Index ใน Test DB
↓
EXPLAIN ใหม่
↓
Benchmark
FiveM EXPLAIN ใช้อย่างไร
ตัวอย่าง:
EXPLAIN
SELECT
`id`,
`model`
FROM `vehicles`
WHERE `owner` = 'license:example';
MariaDB ระบุว่า EXPLAIN แสดงข้อมูลเกี่ยวกับวิธี Execute Query.
FiveM Composite Index คืออะไร
คือ Index หลาย Columns เช่น:
CREATE INDEX `idx_vehicles_owner_stored`
ON `vehicles` (`owner`, `stored`);
MariaDB เรียกว่า Compound/Composite Index.
FiveM Query ช้าหลังข้อมูลเยอะขึ้น
ตรวจ:
Table Size
↓
EXPLAIN
↓
Rows Examined
↓
Index
↓
Query Count
↓
Result Size
เพราะ Query ที่ทำงานเร็วกับ Data ขนาดเล็กอาจมี Scaling Characteristics ต่างเมื่อข้อมูลโตขึ้น
FiveM Index เยอะเกินไปมีผลไหม
มี
MariaDB ระบุว่า Index ทุกตัวต้องได้รับการ Update เมื่อ Insert และ Index จำนวนมากทำให้ Insert ช้าลง.
จึงต้อง Balance:
Read Performance
กับ
Write Performance
FiveM ควร Index identifier ไหม
ถ้า Queries หลักของ Table ใช้:
WHERE `identifier` = ?
บ่อยมาก ก็ควรวิเคราะห์ Index บน Column นี้
แต่ต้องตรวจ Existing Index และ EXPLAIN ก่อน
FiveM ควร Index stored ไหม
ถ้า stored มีเพียง:
0
1
Single-column Index อาจไม่ได้มีประโยชน์มากในหลาย Data Distributions
แต่ Composite Index:
(owner, stored)
อาจมีประโยชน์กับ Query ที่ Filter Owner ก่อน
ต้องวัดด้วย EXPLAIN
FiveM ควร Index created_at ไหม
ขึ้นกับ Queries
ถ้ามี:
WHERE identifier = ?
ORDER BY created_at DESC
อาจพิจารณา Composite Index ตาม Query Pattern
แต่ถ้า created_at ไม่เคยใช้ Filter/Order การสร้าง Index เพียงเพราะมี Column นี้ก็อาจไม่จำเป็น
FiveM เพิ่ม Index แล้ว Restart Server ไหม
Index เป็น Database Schema Object ไม่ได้เป็น FiveM Resource Code
หลัง CREATE INDEX สำเร็จ Database สามารถใช้ Index ตาม Optimizer ได้
อย่างไรก็ตาม Resource Query Behavior และ Connection State ควรถูกทดสอบตาม Environment จริง ไม่ควร Restart Production Server โดยไม่จำเป็นเพียงเพื่อหวังว่า Index จะเริ่มทำงาน
FiveM Index หายหลัง Restart ไหม
Index เป็นส่วนของ Database Schema จึงควรคงอยู่หลัง FiveM Resource/FXServer Restart ตราบใดที่ Database Schema ไม่ถูกเปลี่ยนหรือลบ
ต่างจาก Runtime Data เช่น Entity Handle หรือ Cache
FiveM Index ทำให้ oxmysql เร็วขึ้นไหม
oxmysql เป็น Wrapper ที่ส่ง Query ไปยัง Database
ถ้า Database Query ได้ประโยชน์จาก Index Response Time ที่ oxmysqlได้รับก็สามารถดีขึ้นตาม Database Execution
แต่ oxmysql เองเตือนว่า Query Speed ยังขึ้นกับ Hardware, Database Settings, Version และ Workload.
FAQ FiveM MySQL Index
FiveM MySQL Index คืออะไร
คือ Database Index ที่ MySQL/MariaDB สามารถใช้เพื่อช่วยค้นหา Records ตาม Query Pattern ที่เหมาะสม โดย MariaDB รองรับ Primary, Unique และ Regular Indexes.
EXPLAIN คืออะไร
เป็นคำสั่งสำหรับดูข้อมูลว่า MariaDB วางแผน Execute SELECT, UPDATE หรือ DELETE อย่างไร.
Composite Index คืออะไร
คือ Index ที่มีหลาย Columns เช่น INDEX(owner, stored).
Index เยอะยิ่งดีไหม
ไม่ MariaDB ระบุว่า Index เพิ่มต้นทุนของ Writes และ Redundant Indexes อาจไม่จำเป็น.
INDEX(owner) กับ INDEX(owner, stored) ต้องมีทั้งคู่ไหม
ไม่จำเป็นเสมอไป เพราะ MariaDB ระบุว่า INDEX(a,b) สามารถรองรับ Prefix a ได้ใน Query Pattern ที่เหมาะสม.
ANALYZE TABLE คืออะไร
ใช้วิเคราะห์และอัปเดต Key Distribution/Statistics ที่ Optimizer ใช้ตัดสิน Execution Plan.
FiveM Slow Query ต้องเพิ่ม Index ทุกครั้งไหม
ไม่ ต้องตรวจ EXPLAIN, Query Frequency, Table Size, Result Size และ Resource Code ก่อน เพราะปัญหาอาจไม่ได้มาจาก Index
MySQL.prepare แทน Index ได้ไหม
ไม่ได้ Prepare ช่วย Frequently-called Queries ใน oxmysql แต่ Index เป็น Database Structure สำหรับ Query Optimization คนละ Layer.
Index ช่วย Server Hitch ได้ไหม
หากต้นเหตุคือ SQL Query ที่ช้าเพราะ Database Access Pattern การ Optimize Query/Index อาจช่วยได้ แต่ Cfx.re ระบุว่า Hitch ยังเกิดได้จากปัญหาอื่น เช่น Unoptimized Loops เช่นกัน.
จะรู้ได้อย่างไรว่า Index ช่วยจริง
เปรียบเทียบ:
EXPLAIN ก่อน
Query Timing ก่อน
vs
EXPLAIN หลัง
Query Timing หลัง
ด้วย Data และ Workload ใกล้ Production
ประเด็นสำคัญ
FiveM MySQL/MariaDB Index ไม่ควรถูกสร้างด้วยแนวคิด:
Query ช้า
=
เพิ่ม Index
แต่ควรใช้กระบวนการ:
Query ช้า
↓
mysql_debug
↓
EXPLAIN
↓
SHOW INDEX
↓
ดู WHERE/JOIN/ORDER BY
↓
ออกแบบ Single/Composite Index
↓
EXPLAIN ใหม่
↓
Benchmark
↓
Profiler
MariaDB มี EXPLAIN สำหรับดู Execution Plan และมีทั้ง Single-column, Composite, Covering และ Index Statistics ที่ช่วยในการ Query Optimization.
สิ่งที่ต้องระวังคือ Index ไม่ใช่ของฟรี เพราะ Index ทุกตัวเพิ่มงานให้ Write Operations และ Index ที่ซ้ำซ้อนอาจไม่จำเป็น ดังนั้นอย่า Index ทุก Column หรือสร้าง Index ใหม่ทุกครั้งที่เห็น Slow Query Warning.
สำหรับ FiveM ให้ใช้ oxmysql Debug Timing ร่วมกับ FiveM Profiler เพราะ Cfx.re ระบุว่า SQL Query ที่ใช้เวลานานสามารถทำให้เกิด Hitch Warning ได้ แต่ Profiler ยังช่วยแยกได้ว่าปัญหาอยู่ใน Database หรือ Resource Code ส่วนอื่น.
สำหรับผู้อ่าน comsiam ให้จำสูตร “Slow Query → EXPLAIN → Index → Measure” และ comsiam แนะนำว่าอย่าดูเพียงว่า Query ใช้ Index หรือไม่ แต่ให้ดูทั้ง Query Time, Query Count, Rows, Player Count และ Write Performance ด้วย เพราะเป้าหมายสุดท้ายไม่ใช่มี Index เยอะที่สุด แต่คือให้ Database ทำงานได้เหมาะกับ FiveM Workload จริง
Comments
Post a Comment