ทำไมการนับ (*) ช้าเมื่ออธิบายคำตอบจะรู้ได้อย่างไร


14

คำค้นหานี้: select count(*) from planner_eventใช้เวลานานมากในการรัน - นานมากฉันยอมแพ้และฆ่ามันก่อนที่มันจะเสร็จ อย่างไรก็ตามเมื่อฉันเรียกใช้explain select count(*) from planner_eventฉันสามารถเห็นคอลัมน์ในผลลัพธ์ด้วยจำนวนแถว (14m)

ทำไมการอธิบายถึงสามารถรับจำนวนแถวได้ทันที แต่การนับ (*) ใช้เวลานานในการรัน


COUNT (*) โดยไม่มีสาเหตุที่จะทำให้การสแกนตารางในเครื่องมือ InnoDB .. MyISAM สามารถส่งการนับโดยตรงเนื่องจาก COUNT เป็น keept ในไฟล์ส่วนหัวออกจากตาราง
Raymond Nijland

คำตอบ:


16

อธิบายว่าใช้สถิติที่รวบรวมไว้ก่อนหน้านี้ (ใช้โดยเครื่องมือเพิ่มประสิทธิภาพคิวรี) ทำการselect count(*)อ่านบล็อกข้อมูลทุกคน

นี่คือวิธีที่ประหยัดในการรับจำนวนแถวโดยประมาณ:

select TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME='planner_event';

แม้ว่าคุณจะทำselect count(id)เช่นนั้นอาจใช้เวลานานมากเว้นแต่คุณจะมีดัชนีรองในid(เช่นสมมติว่าidเป็นคีย์หลัก) เนื่องจากข้อมูลทั้งหมด (รวมถึงข้อมูลแถว) ถูกเก็บไว้ในดัชนี B-Tree การดำเนินการ a select count(PK_COLUMN)จึงยังคงมีจำนวน IO มาก (จำเป็นต้องอ่านหน้าข้อมูลทั้งหมด) หากคุณมีดัชนีรองในฟิลด์ PK มันจะสามารถทำ IO ให้น้อยลงเพื่อทำการนับ


I_S.TABLES ช่วยให้คุณเหมือนกันประมาณการว่าEXPLAINจะช่วยให้คุณ
Rick James

แบบสอบถามหายไปAND TABLE_SCHEMA='my_database'มิฉะนั้นคุณจะได้ผลลัพธ์หลายรายการหากคุณมีตารางที่มีชื่อเดียวกันในฐานข้อมูลอื่น
cz

3

อธิบายได้รับตัวเลขจาก "สถิติ" บางอย่างที่ใช้ในการประเมินสิ่งต่าง ๆ สำหรับเครื่องมือเพิ่มประสิทธิภาพ จำนวนนั้นอาจไม่ถูกต้อง - บางครั้งฉันเห็นว่ามันเป็นมากกว่า 2 เท่า (สูงกว่าหรือต่ำกว่า) มากกว่าค่าที่แน่นอน

การดำเนินการCOUNT(*)บนตาราง InnoDB ต้องสแกนตารางเพื่อหลีกเลี่ยงการบันทึกผิดพลาดที่ไม่ว่างถูกแทรก / ลบโดยการเชื่อมต่ออื่น ๆ แต่ยังไม่ได้ "มุ่งมั่น" อันที่จริงมันดีพอที่จะทำการสแกนแบบเต็มบนดัชนีบางตัวไม่จำเป็นต้องเป็นทั้งตาราง (ซึ่งมีPRIMARY KEY)

คุณมี RAM เท่าใด ค่าของinnodb_buffer_pool_sizeคืออะไร? มันอาจช่วยได้หากมีประมาณ 70% ของ RAM

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