เพิ่มประสิทธิภาพการสืบค้น GQL สําหรับกราฟใน Microsoft Fabric

Note

คุณลักษณะนี้อยู่ในการแสดงตัวอย่างสาธารณะ การแสดงตัวอย่างนี้จะมีให้โดยไม่มีข้อตกลงระดับบริการ และไม่แนะนําสําหรับปริมาณงานการผลิต คุณลักษณะบางอย่างอาจไม่ได้รับการสนับสนุนหรืออาจมีความสามารถที่จํากัด สําหรับข้อมูลเพิ่มเติม โปรดดู ข้อกําหนดการใช้งานเพิ่มเติมสําหรับตัวอย่าง Microsoft Azure

บทความนี้ให้คําแนะนําสําหรับการเขียนคิวรี GQL (ภาษาคิวรีกราฟ) ที่ทํางานได้อย่างคาดเดาได้และมีประสิทธิภาพเมื่อทํางานกับกราฟใน Microsoft Fabric คําแนะนําจะขึ้นอยู่กับพฤติกรรมของแพลตฟอร์มปัจจุบันและข้อจํากัดที่บันทึกไว้

สําหรับขีดจํากัดแบบตายตัวเกี่ยวกับขนาดกราฟ ขนาดผลลัพธ์ และการหมดเวลาของคิวรี โปรดดู ข้อจํากัดปัจจุบัน คําแนะนําหลายประการในบทความนี้ยังเกี่ยวข้องกับวิธีที่คุณออกแบบ Schema กราฟของคุณ สําหรับข้อมูลเพิ่มเติม ให้ดูที่ การออกแบบ Schema กราฟ

กรองรูปแบบตั้งแต่เนิ่นๆ

วางตัวกรองภายในรูปแบบกราฟแทนที่จะวางในคําสั่งในภายหลัง ส่วนคําสั่งระดับ WHERE รูปแบบจะลดจํานวนผลลัพธ์ระดับกลางก่อนการรวมและคําสั่งที่ตามมา ซึ่งจะช่วยลดต้นทุนการดําเนินการโดยรวม

ที่แนะนํา: กรองระหว่างการจับคู่รูปแบบ

-- Pattern-level WHERE reduces intermediate results
MATCH (p:Person WHERE p.birthday < 19940101)-[:workAt]->(c:Company WHERE c.id > 1000)
RETURN p.firstName, p.lastName, c.name

หลีกเลี่ยง: การกรองล่าช้าด้วยคําสั่ง FILTER แยกต่างหาก

-- Statement-level filter runs after all pattern matches are produced
MATCH (p:Person)-[:workAt]->(c:Company)
FILTER p.birthday < 19940101 AND c.id > 1000
RETURN p.firstName, p.lastName, c.name

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

เคล็ดลับ

คิดว่าระดับWHEREรูปแบบคล้ายกับเงื่อนไข SQL JOIN ... ON โดยจํากัดการจับคู่ ณ จุดของการประเมินแทนที่จะกรองชุดผลลัพธ์ทั้งหมดในภายหลัง

ส่งคืนเฉพาะคุณสมบัติที่คุณต้องการ

ส่งคืนเฉพาะคุณสมบัติโหนดและเอดจ์ที่สถานการณ์ของคุณต้องการ หลีกเลี่ยงการส่งคืนโหนดแบบเต็มหรือใช้ RETURN * เมื่อคุณต้องการเพียงชุดย่อยของคุณสมบัติ

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

ที่แนะนํา: การฉายภาพที่แคบ

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name

หลีกเลี่ยง: การส่งคืนโหนดเต็ม

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN *

Note

ลบคุณสมบัติชนิดโหนดที่ไม่ได้ใช้ในระหว่างการสร้างแบบจําลองกราฟโดยเลือกไอคอนถังขยะถัดจากแต่ละคุณสมบัติ คุณสมบัติที่น้อยลงต่อโหนดช่วยลดทั้งค่าใช้จ่ายในการ storage และคิวรี

จํากัดขนาดชุดผลลัพธ์

ใช้ LIMIT หรือเงื่อนไขขอบเขตอื่นๆ เมื่อสอบถามโหนดหรือความสัมพันธ์ที่อาจมีคาร์ดินาลลิตี้สูง การจับคู่กราฟที่ไม่มีขอบเขตสามารถสร้างชุดผลลัพธ์ขนาดใหญ่มากที่เข้าใกล้ขีดจํากัดของแพลตฟอร์ม

ที่แนะนํา: ผลลัพธ์ที่มีขอบเขต

MATCH (p:Person)-[:knows]->(friend:Person)
RETURN p.firstName, friend.firstName
LIMIT 1000

หลีกเลี่ยง: การแข่งขันคาร์ดินาลลิตี้สูงที่ไม่มีขอบเขต

MATCH (p:Person)-[:knows]->(friend:Person)
RETURN p.firstName, friend.firstName

สำคัญ

กราฟตัดทอนการตอบสนองที่มีขนาดใหญ่กว่า 64 MB และประสิทธิภาพการรวมอาจไม่เสถียรเมื่อผลลัพธ์เกิน 128 MB ใช้ FILTER, LIMIT, และ GROUP BY เพื่อรักษาผลลัพธ์ให้อยู่ในขอบเขตเหล่านี้ สําหรับข้อมูลเพิ่มเติม โปรดดู ข้อจํากัดปัจจุบัน

ให้การสํารวจตื้นและตรงเป้าหมาย

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

ที่แนะนํา: ขอบเขตที่แน่นหนา

-- Use the narrowest hop range that answers your question
MATCH (p:Person)-[:knows]->{1,3}(friend:Person)
RETURN p.firstName, friend.firstName
LIMIT 1000

หลีกเลี่ยง: การเคลื่อนที่ที่มีความลึกสูงสุดโดยไม่จําเป็นต้องชัดเจน

-- Exploring the full 8-hop limit on a dense graph is expensive
MATCH (p:Person)-[:knows]->{1,8}(friend:Person)
RETURN *

สำคัญ

กราฟรองรับ การกระโดดได้สูงสุดแปดครั้ง ในรูปแบบความยาวตัวแปร ถึงกระนั้น ให้ใช้ขอบเขตที่แคบที่สุดที่สถานการณ์ของคุณอนุญาต ในตัวอย่าง รูปแบบมี {1,3} ราคาถูกกว่า {1,8} กราฟเดียวกันอย่างมาก

ใช้ TRAIL เพื่อป้องกันการเคลื่อนที่ซ้ําซ้อน

ใช้ TRAIL โหมดเส้นทางเพื่อป้องกันไม่ให้กลไกจัดการคิวรีกลับมาที่ขอบเดิมอีกครั้ง ในกราฟหนาแน่น วัฏจักรอาจทําให้เกิดการระเบิดของเส้นทางแบบเอ็กซ์โพเนนเชียล TRAIL ตรวจสอบให้แน่ใจว่าแต่ละขอบได้รับการเยี่ยมชมมากที่สุดหนึ่งครั้งต่อเส้นทาง ซึ่งจะช่วยปรับปรุงทั้งความถูกต้องและประสิทธิภาพ

-- TRAIL prevents revisiting the same :knows edge
MATCH TRAIL (src:Person)-[:knows]->{1,4}(dst:Person)
WHERE src.firstName = 'Alice' AND dst.firstName = 'Bob'
RETURN count(*) AS numPaths

หากไม่มี TRAILคิวรีเดียวกันบนกราฟแบบวนซ้ําสามารถสร้างชุดผลลัพธ์ที่ใหญ่กว่ามาก (และมักจะซ้ําซ้อน)

ใช้ตัวแปรที่ใช้ร่วมกันเพื่อการรวมที่มีประสิทธิภาพ

เมื่อคิวรีต้องการข้อมูลจากหลายความสัมพันธ์ ให้ใช้ตัวแปรที่ใช้ร่วมกันเพื่อรวมรูปแบบบนเอนทิตีเดียวกัน หากไม่มีตัวแปรที่ใช้ร่วมกัน รูปแบบสามารถสร้างผลิตภัณฑ์คาร์ทีเซียน - ทุกการรวมกันของการจับคู่จากทั้งสองรูปแบบ - นําไปสู่ชุดผลลัพธ์ที่ใหญ่กว่ามาก

ที่แนะนํา: ตัวแปร p ที่ใช้ร่วมกันจะรวมรูปแบบ

-- Single shared variable ensures an efficient join
MATCH (p:Person)-[:workAt]->(c:Company),
      (p)-[:isLocatedIn]->(city:City)
RETURN p.firstName, c.name AS company, city.name AS city
LIMIT 1000

หลีกเลี่ยง: รูปแบบอิสระที่ไม่มีตัวแปรที่ใช้ร่วมกัน

-- Without a shared variable, this produces a cartesian product
MATCH (p1:Person)-[:workAt]->(c:Company),
      (p2:Person)-[:isLocatedIn]->(city:City)
RETURN p1.firstName, c.name, p2.firstName, city.name

ผลิตภัณฑ์คาร์ทีเซียนจับคู่ทุกผลลัพธ์จากรูปแบบหนึ่งกับทุกผลลัพธ์จากอีกรูปแบบหนึ่ง ถ้า Person-workAt->Company ตรงกับ 1,000 แถวและ Person-isLocatedIn->City ตรงกับ 500 แถว แบบสอบถามจะส่งกลับ 1,000 × 500 = 500,000 แถว การเพิ่มตัวแปรที่ใช้ร่วมกันจะจํากัดการรวม ดังนั้นจึงส่งคืนเฉพาะคู่ที่ตรงกัน

กําหนดข้อจํากัดที่สําคัญบนโหนด

กําหนด ข้อจํากัดของคีย์โหนด ในประเภทกราฟของคุณ ข้อจํากัดที่สําคัญช่วยให้ระบบสามารถเพิ่มประสิทธิภาพการสืบค้นที่ค้นหาโหนดเฉพาะตามคุณสมบัติหลัก คล้ายกับดัชนีคีย์หลักในฐานข้อมูลเชิงสัมพันธ์

ตัวอย่างเช่น หากประเภทกราฟของคุณกําหนด id เป็นคีย์สําหรับ Person โหนด:

CONSTRAINT person_pk
  FOR (n:Person) REQUIRE n.id IS KEY

จากนั้นคิวรีที่กรอง id สามารถใช้คีย์นั้นสําหรับการค้นหาโดยตรง:

-- Fast: the engine can look up person 12345 directly using the key
MATCH (p:Person WHERE p.id = 12345)-[:workAt]->(c:Company)
RETURN p.firstName, c.name

หากไม่มีตัวกรองในคุณสมบัติคีย์ เอ็นจิ้นจะต้องสแกนทุก Person โหนด:

-- Slower: scans all Person nodes before traversing
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName, c.name

เคล็ดลับ

เมื่อคุณต้องการโหนดเฉพาะ ให้กรองคุณสมบัติคีย์ในรูปแบบ MATCH เพื่อใช้ประโยชน์จากข้อจํากัดที่คุณกําหนดไว้

เลือกชนิดข้อมูลที่เหมาะสม

เลือกชนิดข้อมูลที่เฉพาะเจาะจงที่สุดสําหรับแต่ละคุณสมบัติในระหว่างการสร้างแบบจําลองกราฟ การเลือกประเภทที่เหมาะสมเป็นสิ่งสําคัญสําหรับทั้งประสิทธิภาพการจัดเก็บ storage และประสิทธิภาพการสืบค้น ตัวอย่างเช่น การเปรียบเทียบตัวเลขใน INT คุณสมบัติจะเร็วกว่าการเปรียบเทียบสตริงในค่าที่ STRING เท่ากัน

สําหรับชนิดข้อมูลที่รองรับ โปรดดู ข้อจํากัดปัจจุบัน — ชนิดข้อมูล และ ชนิดคุณสมบัติที่รองรับ

หากเป็นไปได้ ให้ดึงข้อมูลเอนทิตีที่เกี่ยวข้องในรูปแบบกราฟเดียวแทนที่จะออกคิวรีแยกต่างหากที่ข้ามขอบเดียวกันอย่างอิสระ การรวมการสํารวจจะช่วยหลีกเลี่ยงการจับคู่รูปแบบที่ซ้ําซ้อนและป้องกันปัญหาการสืบค้น N+1 โดยที่การสืบค้นเริ่มต้นหนึ่งรายการจะทริกเกอร์การสืบค้นแยกต่างหากสําหรับแต่ละแถวผลลัพธ์

ที่แนะนํา: รูปแบบรวมเดี่ยว

MATCH (c:Customer)-[:purchased]->(o:Order)-[:contains]->(product:Product)
RETURN c.id, o.id, product.name
LIMIT 1000

หลีกเลี่ยง: คิวรีสองแบบแยกกันที่ข้ามขอบเดียวกันCustomer → Order

-- Query 1: fetch 100 orders
MATCH (c:Customer)-[:purchased]->(o:Order)
RETURN c.id, o.id

-- Query 2: run once per order to get products (N+1 problem)
MATCH (o:Order)-[:contains]->(product:Product)
RETURN o.id, product.name

ทดสอบการสืบค้นกับปริมาณข้อมูลที่สมจริง

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

  • ชอบรูปร่างคิวรีแบบอนุรักษ์นิยมที่มีตัวกรองและขีดจํากัด
  • หลีกเลี่ยงการสืบค้น "ส่งคืนทุกอย่าง" แบบสํารวจกับกราฟขนาดใหญ่
  • ตรวจสอบระยะเวลาการสืบค้นที่สัมพันธ์กับขีดจํากัดการหมดเวลา 20 นาที