วิธีหนึ่งที่แน่นอนในการเพิ่มความเร็วใน ALTER TABLE คือการลบดัชนีที่ไม่จำเป็นออก
นี่คือขั้นตอนเริ่มต้นในการโหลดเวอร์ชันใหม่ของตาราง
CREATE TABLE s_relations_new LIKE s_relations;
#
# Drop Duplicate Indexes
#
ALTER TABLE s_relations_new
DROP INDEX source_persona_index,
DROP INDEX target_persona_index,
DROP INDEX target_persona_relation_type_index
;
โปรดทราบสิ่งต่อไปนี้:
ฉันปล่อย source_persona_index เนื่องจากเป็นคอลัมน์แรกในดัชนีอื่น ๆ 4 รายการ
- unique_target_persona
- unique_target_object
- source_and_target_object_index
- source_target_persona_index
ฉันทำ target_persona_index ลดลงเพราะเป็นคอลัมน์แรกในดัชนีอีก 2 รายการ
- target_persona_relation_type_index
- target_persona_relation_type_message_id_index
ฉันลดเป้าหมาย target_persona_relation_type_index เพราะ 2 คอลัมน์แรกยังอยู่ใน target_persona_relation_type_message_id_index
ตกลงนั่นคือการดูแลดัชนีที่ไม่จำเป็น มีดัชนีใดบ้างที่มีภาวะหัวใจต่ำ นี่คือวิธีการตรวจสอบว่า:
เรียกใช้แบบสอบถามต่อไปนี้:
SELECT COUNT(DISTINCT sent_at) FROM s_relations;
SELECT COUNT(DISTINCT message_id) FROM s_relations;
SELECT COUNT(DISTINCT target_object_id) FROM s_relations;
ตามคำถามของคุณมีแถวประมาณ 80,000,000 แถว โดยทั่วไปแล้ว MySQL Query Optimizer จะไม่ใช้ดัชนีหากความสำคัญของคอลัมน์ที่เลือกมีค่ามากกว่า 5% ของจำนวนแถวของตาราง ในกรณีนี้จะเท่ากับ 4,000,000
- ถ้า
COUNT(DISTINCT sent_at)
> 4,000,000
- แล้วก็
ALTER TABLE s_relations_new
DROP INDEX sent_at_index;
- ถ้า
COUNT(DISTINCT message_id)
> 4,000,000
- แล้วก็
ALTER TABLE s_relations_new
DROP INDEX message_id_index;
- ถ้า
COUNT(DISTINCT target_object_id)
> 4,000,000
- แล้วก็
ALTER TABLE s_relations_new
DROP INDEX target_object_index;
เมื่อพิจารณาถึงประโยชน์หรือความไร้ประโยชน์ของดัชนีเหล่านั้นแล้วคุณสามารถโหลดข้อมูลใหม่ได้
#
# Change the Column Name
# Load the Table
#
ALTER TABLE s_relations_new CHANGE sent_at sent_at_new int(11) DEFAULT NULL;
INSERT INTO s_relations_new SELECT * FROM s_relations;
ใช่ไหม ไม่มี !!!
หากเว็บไซต์ของคุณใช้งานไม่ได้ตลอดเวลาอาจมีการแทรก INSERTs กับ s_relations ระหว่างการโหลด s_relations_new คุณจะเรียกคืนแถวที่หายไปเหล่านั้นได้อย่างไร
ไปหา id สูงสุดใน s_relations_new และต่อท้ายทุกอย่างหลังจาก ID นั้นจาก s_relations เพื่อให้มั่นใจว่าตารางถูกตรึงและใช้สำหรับการอัปเดตนี้เท่านั้นคุณต้องมีเวลาหยุดทำงานเล็กน้อยเพื่อรับแถวสุดท้ายที่แทรกเข้าไปใน s_relation_new นี่คือสิ่งที่คุณทำ:
ในระบบปฏิบัติการรีสตาร์ท mysql เพื่อให้ไม่มีใครสามารถเข้าสู่ระบบได้ แต่รูท @ localhost (ปิดใช้งาน TCP / IP):
$ service mysql restart --skip-networking
ถัดไปเข้าสู่ mysql และโหลดแถวสุดท้าย:
mysql> SELECT MAX(id) INTO @maxidnew FROM s_relations_new;
mysql> INSERT INTO s_relations_new SELECT * FROM s_relations WHERE id > @maxidnew;
mysql> ALTER TABLE s_relations RENAME s_relations_old;
mysql> ALTER TABLE s_relations_new RENAME s_relations;
จากนั้นเริ่ม mysql ใหม่ตามปกติ
$ service mysql restart
ตอนนี้ถ้าคุณไม่สามารถลบ mysql ได้คุณจะต้องทำการเปลี่ยนเหยื่อและเปลี่ยนเป็น s_relations เพียงเข้าสู่ mysql และทำสิ่งต่อไปนี้:
mysql> ALTER TABLE s_relations RENAME s_relations_old;
mysql> SELECT MAX(id) INTO @maxidnew FROM s_relations_new;
mysql> INSERT INTO s_relations_new SELECT * FROM s_relations_old WHERE id > @maxidnew;
mysql> ALTER TABLE s_relations_new RENAME s_relations;
ให้มันลอง !!!
ถ้ำ: เมื่อคุณพอใจกับการดำเนินการนี้แล้วคุณสามารถวางโต๊ะเก่าตามความสะดวกได้เร็วที่สุด:
mysql> DROP TABLE s_relations_old;
SHOW CREATE TABLE tblname\G
แสดงคอลัมน์ที่จำเป็นต้องเปลี่ยนประเภทข้อมูลของคอลัมน์และชื่อใหม่สำหรับคอลัมน์