Google จัดเก็บตารางคำค้นหาขนาดใหญ่ของคุณอย่างไร และมีผลกับคุณอย่างไร

เผยแพร่แล้ว: 2016-02-24

นี่คือการติดตั้งการพูดคุยทางเทคนิคของบล็อกของเรา ซึ่งนำเสนอโดย Adam Knox นักพัฒนาที่มีความสามารถพิเศษ

แม้ว่า Big Query จะใช้ไวยากรณ์ที่คล้ายกับ SQL มาก แต่จริงๆ แล้วต้องใช้ชั้นเชิงที่แตกต่างกันอย่างมากในการแก้ปัญหาสำหรับการประมวลผลข้อมูลจำนวนมาก Big Query มีแนวโน้มที่จะใช้กำลังดุร้ายและไม่ได้ใช้ดัชนีจริงๆ ดังนั้นข้อมูลจำนวนมากจึงหมายถึงตัวประมวลผลจำนวนมากและเวลาในการประมวลผล ในการดึงสิ่งนี้ออก Google ได้ใช้วิธีการจัดเก็บข้อมูลที่แตกต่างออกไปซึ่งอาจส่งผลต่อการออกแบบข้อความค้นหาของคุณ

รูปแบบไฟล์

เมื่อมีการสร้างตาราง Google จะใช้รูปแบบ ColumnIO เพื่อจัดเก็บข้อมูลของคุณ แต่ละคอลัมน์จะถูกจัดเก็บเป็นไฟล์แยกกัน ยกเว้นเป็นฟิลด์ที่ซ้ำกัน หากคุณมีตารางที่มีคอลัมน์: name (string), phoneNumbers (repeated integer); ชื่อจะถูกเก็บไว้ในบรรทัดเดียวกับชื่ออื่น และหมายเลขโทรศัพท์ทั้งหมดที่เกี่ยวข้องกับชื่อนั้นจะถูกเก็บไว้ในบรรทัดเดียวกับหมายเลขโทรศัพท์ คอลัมน์ยังสามารถแยกออกได้เช่นกันหากคอลัมน์ใหญ่เกินไป แต่นั่นจะไม่มีผลกระทบต่อเวิร์กโฟลว์

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

การจัดเก็บไฟล์

หากคุณสร้างตารางแล้ว คุณจะรู้สึกปลอดภัยพอสมควรว่าจะไม่ย้ายไปไหน เพราะเมื่อสร้างไฟล์แล้ว ไฟล์เหล่านั้นจะถูกจัดเก็บไว้ในศูนย์ข้อมูลที่แตกต่างกันสามแห่ง และแม้แต่สามแห่งภายในศูนย์ข้อมูลแต่ละแห่ง เนื่องจาก Big Query ทำให้ตัวประมวลผลมีปัญหา ข้อมูลจึงต้องสามารถเข้าถึงได้ง่าย ข้อแม้นี้เป็นชุดข้อมูลชั่วคราว มีตัวเลือกในการระบุเวลาหมดอายุสำหรับตารางภายในชุดข้อมูล และตารางจะหายไปเมื่อเก่ากว่าวันหมดอายุนี้

ลำดับชั้นของตาราง

โปรเจ็กต์มีความสามารถในการจัดเก็บชุดข้อมูล ซึ่งแต่ละชุดสามารถมีตารางได้ คำสั่งแบบเต็มสำหรับการเข้าถึงตารางในไวยากรณ์ Big Query คือ [projectname:datasetname.tablename] อย่างไรก็ตาม คำสั่งนี้สามารถย่อให้เหลือ dataset.tablename หากคุณเข้าถึงตารางจากโครงการที่คุณกำลังทำงานอยู่

การแบ่งข้อมูลที่เกี่ยวข้องออกเป็นตารางแยกกัน (เช่น ตามวันที่หรือหลังจากเหตุการณ์ใดเหตุการณ์หนึ่งเกิดขึ้น) อาจเป็นประโยชน์สำหรับการสร้างการสืบค้นที่ดูแลรักษาได้มากขึ้น เนื่องจากโดยทั่วไปแล้วการสืบค้นจะทำงานในแถวทั้งหมดในตาราง ซึ่งหมายความว่าคุณอาจต้องการดูตารางหลายตาราง ดังนั้นจึงมีสิ่งที่เรียกว่าตารางเมตาซ่อนอยู่ในชุดข้อมูลแต่ละชุดที่สามารถเข้าถึงได้ที่ [projectname:datasetname.__TABLES__] และมีข้อมูลเกี่ยวกับแต่ละตารางในชุดข้อมูลและสามารถใช้สำหรับรวมตารางสำหรับ การสอบถาม

คำสั่ง TABLE_QUERY เป็นคำสั่งที่อนุญาตให้รวมตารางที่เหมือนกันหลายตารางก่อนเรียกใช้แบบสอบถามในการรวม และคอลัมน์ใดๆ ใน __TABLES__ สามารถใช้เพื่อสร้างการรวมนี้ ตัวอย่างเช่น หากฉันต้องการแนวคิดเกี่ยวกับเวลาตอบสนองตั้งแต่วันที่ 1 มกราคม 2016 สำหรับโครงการ ฉันสามารถเรียกใช้แบบสอบถามต่อไปนี้ซึ่งแสดงเวลาตอบสนองขั้นต่ำ ค่ามัธยฐาน และสูงสุด:

 SELECT QUANTILES((protoPayload.endTime - protoPayload.startTime), 3) AS responseTimeBucketsInMilliseconds FROM (TABLE_QUERY(appengine_logs, "table_id CONTAINS 'appengine_googleapis_com_request_log' AND creation_time > 1451606400000"))

เนื่องจากมีการใช้เพียงสองคอลัมน์แต่ละคอลัมน์ที่มีจำนวนเต็ม นี่จึงเป็นข้อความค้นหาราคาถูกที่สมเหตุสมผล ($0.0003) แม้ว่าจะมีการเข้าถึง 28+ ที่ฉันได้รับแจ้งว่า 1.857TB ตามข้อความค้นหาด้านล่าง และจะมีค่าใช้จ่ายประมาณ 9$ เพื่อเข้าถึงทุกฟิลด์จาก .

 SELECT SUM(size_bytes)/1000000000 FROM [repcore-prod:appengine_logs.__TABLES__] WHERE table_id CONTAINS 'appengine_googleapis_com_request_log' AND creation_time > 1451606400000

กำลังอัปเดตไฟล์

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

ตารางหาร

ในบางสถานการณ์แม้แต่การเข้าถึงคอลัมน์เดียวก็มากเกินไปที่จะจัดการใน Big Query ฉันขอเสนอคำถามที่ใช้ไม่ได้ต่อไปนี้ซึ่งส่งคืน ID รายชื่อตามวันที่สร้างรายการ:

 SELECT lid FROM [repcore-prod:datastore.LIS] ORDER BY ct

ในทางเทคนิค เมื่อเร็ว ๆ นี้มันเป็นไปได้สำหรับสิ่งนี้ที่จะประสบความสำเร็จ แต่ไม่ใช่สำหรับคนที่ Vendasta เนื่องจากต้องมีการเปิดใช้งานระดับการเรียกเก็บเงินที่สูงขึ้น เนื่องจากไม่มีดัชนีที่สั่งซื้อล่วงหน้า จึงมีการประมวลผลข้อมูลจำนวนเล็กน้อยอย่างเข้มข้น ดังนั้นในกรณีนี้จึงถูกเรียกเก็บเงินสำหรับการประมวลผล การเปลี่ยนระดับการเรียกเก็บเงินสามารถทำได้ในการสืบค้นแบบโต้ตอบใน Big Query UI โดยทำเครื่องหมายที่ "อนุญาตไม่จำกัด" (หากเปิดใช้งาน) ใต้ปุ่ม "ตัวเลือก"

สมมติว่าการสืบค้นของคุณมีประสิทธิภาพมากที่สุด มีสองวิธีที่เหลือในการลดขนาดตารางเพื่อหลีกเลี่ยงขีดจำกัดฮาร์ดประเภทนี้ อย่างแรกคือนักตกแต่งตารางเวลาและคนที่สองคือแฮช

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับนักตกแต่งโต๊ะได้ที่นี่ แตกต่างจากการกรองผลลัพธ์โดยใช้คำสั่งเช่น LIMIT/WHERE/HAVING/OMIT ตกแต่งตารางจะลดค่าใช้จ่ายในการสืบค้นตารางจริง ๆ เพราะจะไม่เข้าถึงข้อมูลนอกช่วงที่กำหนด น่าเสียดายที่วิธีนี้ใกล้จะไร้ประโยชน์ที่ Vendasta เพราะแม้แต่สำหรับตารางอย่าง ListingHistoryModel ที่เราส่งกระแสข้อมูลจริงๆ เรายังคงวางทั้งตารางและแทนที่มันทุกวันด้วยแบบจำลองหากมาจาก NDB หมายความว่าผู้ตกแต่งตารางเวลาจะทำงานบน ListingHistoryModel หากคุณสนใจเฉพาะรายการของวันปัจจุบัน

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

ผลการค้นหา

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