Google จัดเก็บตารางคำค้นหาขนาดใหญ่ของคุณอย่างไร และมีผลกับคุณอย่างไร
เผยแพร่แล้ว: 2016-02-24นี่คือการติดตั้งการพูดคุยทางเทคนิคของบล็อกของเรา ซึ่งนำเสนอโดย Adam Knox นักพัฒนาที่มีความสามารถพิเศษ
แม้ว่า Big Query จะใช้ไวยากรณ์ที่คล้ายกับ SQL มาก แต่จริงๆ แล้วต้องใช้ชั้นเชิงที่แตกต่างกันอย่างมากในการแก้ปัญหาสำหรับการประมวลผลข้อมูลจำนวนมาก Big Query มีแนวโน้มที่จะใช้กำลังดุร้ายและไม่ได้ใช้ดัชนีจริงๆ ดังนั้นข้อมูลจำนวนมากจึงหมายถึงตัวประมวลผลจำนวนมากและเวลาในการประมวลผล ในการดึงสิ่งนี้ออก Google ได้ใช้วิธีการจัดเก็บข้อมูลที่แตกต่างออกไปซึ่งอาจส่งผลต่อการออกแบบข้อความค้นหาของคุณ
รูปแบบไฟล์
เมื่อมีการสร้างตาราง Google จะใช้รูปแบบ ColumnIO เพื่อจัดเก็บข้อมูลของคุณ แต่ละคอลัมน์จะถูกจัดเก็บเป็นไฟล์แยกต่างหากโดยมีข้อยกเว้นว่าเป็นฟิลด์ที่ซ้ำกัน หากคุณมีตารางที่มีคอลัมน์: ชื่อ (สตริง), phoneNumbers (จำนวนเต็มซ้ำ); ชื่อจะถูกเก็บไว้ในบรรทัดเดียวกับชื่ออื่น ๆ และหมายเลขโทรศัพท์ทั้งหมดที่เกี่ยวข้องกับชื่อนั้นจะถูกเก็บไว้ในบรรทัดเดียวกับหมายเลขโทรศัพท์ คอลัมน์ยังสามารถถูกแยกออกได้เช่นกันหากมีขนาดใหญ่เกินไป แต่นั่นจะไม่มีผลกระทบต่อเวิร์กโฟลว์
การรู้สิ่งนี้ทำให้สามารถเรียกใช้การสืบค้นข้อมูลได้เร็วขึ้นโดยไม่ประมวลผลคอลัมน์ที่คุณไม่สนใจจริงๆ และในบางกรณีอาจทำให้ไม่สามารถเรียกใช้การสืบค้นข้อมูลก่อนหน้านี้ได้ การสืบค้นข้อมูลอาจมีราคาถูกลงด้วยเนื่องจากระบบจะเรียกเก็บเงินตามจำนวนข้อมูลที่ประมวลผล และหากไม่มีคอลัมน์ในแบบสอบถาม ข้อมูลนั้นก็จะไม่ได้รับการประมวลผล
การจัดเก็บไฟล์
หากคุณสร้างตารางแล้ว คุณจะรู้สึกปลอดภัยพอสมควรว่าจะไม่ไปไหน เพราะเมื่อไฟล์ของคุณถูกสร้างขึ้นแล้ว ไฟล์เหล่านั้นจะถูกจัดเก็บไว้ในศูนย์ข้อมูลที่แตกต่างกันสามแห่ง และแม้แต่สามแห่งภายในศูนย์ข้อมูลแต่ละแห่ง เนื่องจาก 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 ตั้งให้และปล่อยให้มันหายไปหลังจากผ่านไปหนึ่งวัน หากคุณเคยพบ “การตอบสนองมากเกินไปที่จะส่งคืน” นั่นเป็นเพราะพวกเขาปกป้องคุณจากตัวคุณเอง ง่ายต่อการสร้างตารางขนาดมหึมา (โดยเฉพาะการรวมแบบไขว้) หากสิ่งนี้เกิดขึ้นและคุณคาดว่าจะเกิดขึ้น คุณจะต้องตั้งชื่อตารางและเปิดใช้งานตัวเลือก "อนุญาตผลลัพธ์จำนวนมาก" หากคุณค้นหาซ้ำโดยไม่มีการสตรีมแถวใหม่ คุณก็จะได้ผลลัพธ์ที่แคชไว้หากรายการเหล่านั้นยังคงอยู่
