mysql ใช้เวลาในการส่งข้อมูลนานเกินไป


9

ฉันมีตารางง่าย ๆ ที่มีล้านเรคคอร์ด (14,000,000) และสำหรับเคียวรี่ธรรมดา ๆ มันใช้เวลามากเกินไปในการ "ส่งข้อมูล"

โต๊ะ

CREATE TABLE IF NOT EXISTS details (
  id int(11) NOT NULL,
  date date NOT NULL,
  time int(2) NOT NULL,
  minutes_online decimal(5,0) NOT NULL,
  minutes_playing decimal(5,0) NOT NULL,
  minutes_chatting decimal(5,0) NOT NULL,
  minutes_away decimal(5,0) NOT NULL
  PRIMARY KEY (id,date,time)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

แบบสอบถามง่ายๆ

mysql> SELECT * FROM details WHERE id = 3014595;

อธิบาย

mysql> EXPLAIN SELECT * FROM details WHERE id = 3014595;
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| id | select_type | table     | type | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | details   | ref  | PRIMARY       | PRIMARY | 4       | const | 1482 |       |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+

โปรไฟล์สำหรับแบบสอบถาม

mysql> SHOW PROFILE FOR QUERY 1;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000024 |
| checking query cache for query | 0.000078 |
| checking permissions           | 0.000014 |
| Opening tables                 | 0.000126 |
| System lock                    | 0.000011 |
| Table lock                     | 0.000030 |
| init                           | 0.000027 |
| optimizing                     | 0.000117 |
| statistics                     | 0.040077 |
| preparing                      | 0.000029 |
| executing                      | 0.000006 |
| Sending data                   | 7.536960 |
| end                            | 0.000013 |
| query end                      | 0.000004 |
| freeing items                  | 0.000037 |
| storing result in query cache  | 0.000006 |
| logging slow query             | 0.000003 |
| cleaning up                    | 0.000006 |
+--------------------------------+----------+

อย่างที่คุณเห็นSELECTคำสั่งนั้นใช้ดัชนีและอ่านเพียงแถว 1482 เท่านั้น กระนั้นคิวรีใช้เวลา 7.536960 วินาทีในการส่งข้อมูล มันเป็นเหมือนแบบสอบถามที่อ่านมากขึ้นแถวที่จำเป็น

มันเป็นแบบสอบถามง่ายๆมีเพียง 7 ฟิลด์ (แถวเฉลี่ย 59 ไบต์) และไม่มีฟังก์ชั่นแฟนซี มีความคิดอะไรที่ทำให้เกิดสิ่งนี้

หมายเหตุ: id คือ ID ผู้ใช้ ผู้ใช้แต่ละคนอาจมีรายการอย่างน้อยหนึ่งรายการสำหรับทุก ๆ ชั่วโมงของทุกวัน ดังนั้น id จึงไม่ซ้ำกัน

แก้ไข:ฉันมีตารางอื่นที่มีโครงสร้างเดียวกันและอีกแถว (34 ล้าน) ถ้าฉันเรียกใช้แบบสอบถามเดียวกันในตารางที่มีขนาดใหญ่กว่านี้มันจะส่งคืนผลลัพธ์ในเวลาน้อยกว่า 1 วินาที

ข้อแตกต่างเพียงอย่างเดียวคือตารางที่ใหญ่กว่าจะไม่ได้รับข้อความค้นหามากเท่ากับตารางที่เล็กกว่า

  • เป็นไปได้หรือไม่ที่จำนวนการสืบค้นทำให้กระบวนการช้าลง? แคช MySQL เปิดอยู่ ฉันยัง CakePHP แคชแบบสอบถามเพื่อลดจำนวนการค้นหา
  • เป็นไปได้หรือไม่ว่าไฟล์ที่บันทึกตารางเสียหายหรือบางอย่าง

อัปเดต ปัญหาได้รับการแก้ไขโดยแยกชั้นข้อมูลออกจากชั้นเว็บ ชั้นข้อมูลยังได้รับการอัพเกรดบน RAM และทำงานบน raid10


วิธีการหลายแถวไม่SELECTกลับมา?
hjpotter92

1591 rows in set (16.48 sec)ฉันเรียกใช้แบบสอบถามอีกครั้งนี่คือเหตุผลว่าทำไมช่วงเวลาจึงแตกต่างกัน ตอนนี้ใช้เวลา 16 วินาที (!!)
rlcabral

แทนที่จะใช้ * ลองใช้คอลัมน์แล้วดูว่ามันทำให้เกิดความแตกต่างอย่างไร
Muhammad Raheel

Nope ผลลัพธ์เดียวกัน
rlcabral

พยายามทำให้คอลัมน์ ID เป็นดัชนีหลักอย่างง่าย เนื่องจาก ID ควรเป็นฟิลด์ที่ไม่ซ้ำกันคุณไม่จำเป็นต้องสร้างดัชนีที่ซับซ้อนด้วย การทำเช่นนี้จะทำให้การค้นหาของคุณด้วยคีย์หลักอย่างรวดเร็วเหมือน Lightspeed
Alexander Pravdin

คำตอบ:


1

สำหรับใครก็ตามที่สะดุดกับคำถามนี้และสงสัยว่าแม้จะไม่มีการอัพเกรด RAM ทำไมการส่งข้อมูลถึงใช้เวลานานกว่านั้นมาก เป็นเพราะการส่งข้อมูลรวมถึงเวลาในการค้นหาข้อมูลที่จะส่ง

https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html

เธรดกำลังอ่านและประมวลผลแถวสำหรับคำสั่ง SELECT และส่งข้อมูลไปยังลูกค้า เนื่องจากการดำเนินการที่เกิดขึ้นในระหว่างสถานะนี้มักจะทำการเข้าถึงดิสก์จำนวนมาก (อ่าน) จึงมักจะเป็นสถานะที่ทำงานยาวนานที่สุดตลอดอายุการใช้งานของแบบสอบถามที่กำหนด


-2

ลองปรับตารางให้เหมาะสมโดยใช้แท็บตารางเพิ่มประสิทธิภาพและตรวจสอบสถานะ

การเปลี่ยนแปลงครั้งใหญ่จะต้องทำ:

Alter table tablename engine = 'INNODB'

สิ่งนี้จะช่วยคุณล็อตและอาจมีคีย์หลักหนึ่งตัวในตาราง แต่คุณได้เพิ่มสามคอลัมน์เป็นคีย์หลัก


-3

สร้างดัชนีแยกต่างหากสำหรับรหัส:

แก้ไขรายละเอียดตารางเพิ่มคีย์ d1 (id);

ในการทำให้ดัชนีนี้มีผลบังคับใช้ให้รีสตาร์ท MySQL หรือ

วิเคราะห์รายละเอียดตาราง

หากเป็นไปได้คุณสามารถเปลี่ยนฐานข้อมูลเป็น InnoDB เพื่อรองรับการทำธุรกรรมและผลประโยชน์อื่น ๆ


สิ่งนี้จะช่วยได้อย่างไร
โคลิน 't ฮาร์ต
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.