อัลกอริทึมสำหรับการค้นหาแท็กที่รวดเร็ว


16

ปัญหาดังต่อไปนี้

  • มีชุดเอนทิตี้เรียบง่าย E แต่ละชุดมีแท็ก T ติดอยู่ แต่ละเอนทิตีอาจมีแท็กจำนวนเท่าใดก็ได้ จำนวนเอนทิตีทั้งหมดอยู่ใกล้ 100 ล้านและจำนวนแท็กทั้งหมดประมาณ 5000

ดังนั้นข้อมูลเริ่มต้นจะเป็นดังนี้:

E1 - T1, T2, T3, ... Tn
E2 - T1, T5, T100, ... Tk
..
Ez - T10, T12, ... Tl

ข้อมูลเริ่มต้นนี้มีการปรับปรุงค่อนข้างน้อย

  • แอพของฉันสร้างนิพจน์เชิงตรรกะบนแท็กเช่นนี้:

    T1 & T2 & T3 | (T5 &! T6)

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

สิ่งที่ฉันได้ตอนนี้คือการค้นหาตารางในหน่วยความจำง่าย ๆ ให้เวลาฉันในการประมวลผล 5-10 วินาทีในเธรดเดียว

ฉันอยากรู้อยากเห็นมีวิธีที่มีประสิทธิภาพในการจัดการสิ่งนี้หรือไม่? คุณจะแนะนำวิธีใด มีอัลกอริทึมทั่วไปหรือโครงสร้างข้อมูลสำหรับสิ่งนี้หรือไม่?

ปรับปรุง

ชี้แจงเล็กน้อยตามที่ร้องขอ

  1. Tวัตถุเป็นสตริงคงที่ค่อนข้างสั้นจริง ๆ แต่มันไม่สำคัญเลย - เราสามารถกำหนด ID และดำเนินการกับจำนวนเต็มได้เสมอ
  2. เราสามารถจัดเรียงได้แน่นอน

1
คือT1การอ้างอิงวัตถุเดียวกันสำหรับE1, E2etc?
Reactgular

แท็กเปรียบเทียบกันอย่างไร สามารถจัดเรียงแท็กเพื่อให้T2 < T3เป็นจริงได้เสมอ
Reactgular

แท็กเป็นไบนารีหรือไม่ คือT1เป็นทั้งtrueหรือfalseหาได้รับEและไม่ตัวแปรบนพื้นฐานของข้อมูล? (เช่นModel = "V5") หรือT1การแสดงออกของตัวแปรเป็นModel = <input>อย่างไร
Bobson

คำตอบ:


4

ฉันจะทำใน sql มีตารางลิงค์EntityCategoryระหว่างeidนิติบุคคลcidอ้างอิงและ หมวดหมู่อ้างอิงโดยใช้การรวมตัวเอง:

    select count(ec1.eid)
    from EntityCategory ec1 
    left join EntityCategory ec2 on ec1.eid=ec2.eid 
    left join EntityCategory ec3 on ec1.eid=ec3.eid 
    ...
    where 
      ec1.cid={categoryId1} and 
      ec2.cid={categoryId2} and
      ec3.cid={categoryId3} ...

1
+1 นี่คือดินแดน DB คลาสสิก คำตอบอื่น ๆ อาจมีความคิดที่สมเหตุสมผลวิธีการทำรหัสด้วยตนเอง แต่ควรเป็นวิธีสุดท้าย
MSalters

ฉันจะเลือก sql เป็นเทคนิคในการแก้ปัญหานี้ ฐานข้อมูลส่วนใหญ่จะเหมาะสวยสำหรับขั้นตอนวิธีการเหล่านี้ :)
winkbrace

3

หลังจากเขียนคำตอบนี้แล้วฉันน่าจะตั้งคำถามว่า“ กว้างเกินไป” - เราสามารถพูดคุยเกี่ยวกับกลยุทธ์ต่าง ๆ ในยุคสมัยได้ในตอนท้ายมาตรฐานจะต้องมีการเรียกใช้กับข้อมูลของคุณ

แต่ละแท็กสามารถแสดงเป็นจำนวนเต็มได้อย่างมีประสิทธิภาพ แต่ละเอนทิตีมีชุดของแท็ก การเลือกการนำชุดที่ถูกต้องไปใช้นั้นมีความสำคัญทั้ง B-trees และ Array ที่เรียงลำดับนั้นเป็นไปได้ ด้วยชุดนี้เราจะทำการทดสอบความเป็นสมาชิกเท่านั้น เนื่องจากโครงสร้างทั้งสองทำสิ่งนี้ในO (log t) (ด้วยแท็กtต่อเอนทิตี) ฉันต้องการอาร์เรย์เนื่องจากการแสดงหนาแน่น

ตอนนี้เราสามารถกรองเอนทิตีทั้งหมดในการดำเนินการO (n · log t · p)โดยที่pคือความยาวพา ธ เฉลี่ยในแผนผังการตัดสินใจของเพรดิเคต ต้นไม้การตัดสินใจนี้สามารถสั่งซื้อเพื่อให้สามารถตัดสินใจได้อย่างรวดเร็ว หากไม่มีข้อมูลทางสถิติเป็นไปได้ที่จะแยกแยะ subexpression ทั่วไปเท่านั้น

ลำดับที่ค้นหาเอนทิตีนั้นไม่สำคัญจริงๆ ในทางกลับกันมันจะเป็นประโยชน์ในการจัดเรียงดังกล่าวว่าหน่วยงานที่ดัชนี0จะiทุกคนมีแท็กบางอย่างในขณะที่ส่วนที่เหลือไม่ได้ สิ่งนี้จะลดค่าnเมื่อค้นหาแท็กเฉพาะนี้ (ในแผนผังการตัดสินใจนี่ควรเป็นการทดสอบครั้งแรก) สิ่งนี้สามารถขยายได้หลายระดับ แต่สิ่งนี้จะซับซ้อนและใช้หน่วยความจำO (2 k )ด้วยkระดับ ด้วยหลายระดับแท็กที่ได้รับผลกำไรสูงสุดควรตัดสินใจก่อนโดยที่จำนวนนั้นคือจำนวนเอนทิตีที่ไม่ต้องค้นหาเท่าความน่าจะเป็นที่จะทิ้งแท็กนั้น กำไรจะสูงสุดสำหรับโอกาส 50:50 หรือเมื่อ 50% ของเอนทิตีมีแท็กเฉพาะนี้ สิ่งนี้จะช่วยให้คุณปรับให้เหมาะสมแม้ว่าจะไม่รู้จักรูปแบบการเข้าถึง

นอกจากนี้คุณยังสามารถสร้างชุดว่าดัชนีหน่วยงานโดยแต่ละแท็กที่ใช้ - หนึ่งชุดกับหน่วยงานทั้งหมดต่อไปสำหรับT1 T2การเพิ่มประสิทธิภาพที่ชัดเจน (พื้นที่และเวลา) คือหยุดเมื่อชุดประกอบด้วยองค์ประกอบมากกว่าครึ่งและเพื่อบันทึกองค์ประกอบเหล่านั้นที่ไม่มีแท็กนี้ - ด้วยวิธีนี้การสร้างดัชนีสำหรับแท็กทั้งหมดจะใช้เวลาน้อยกว่า½ · n · tพื้นที่ (ด้วยจำนวนแท็กทั้งหมด) โปรดทราบว่าการบันทึกชุดเสริมสามารถทำให้การเพิ่มประสิทธิภาพอื่น ๆ ยากขึ้น อีกครั้งฉันจะ (เรียงลำดับ) อาร์เรย์สำหรับชุด

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

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

หากเราใช้อาร์เรย์ที่เรียงลำดับเพื่อนำชุดดัชนีไปใช้นั้นขั้นตอนการประเมินผลหลายขั้นตอนสามารถนำไปใช้เป็นการรวมการดำเนินการ T1 & T2หมายความว่าเราใช้T1และT2รายการจัดสรรขนาดเป้าหมายของขนาดอินพุตที่ใหญ่กว่าและดำเนินการอัลกอริทึมต่อไปนี้จนกว่าอินพุตทั้งสองจะว่างเปล่า: ถ้าT1[0] < T2[0]แล้วT1++(ทิ้งหัว) หากแล้วT1[0] > T2[0] T2++หากทั้งสองหัวมีค่าเท่ากันจากนั้นคัดลอกตัวเลขที่มากกว่าไปยังอาร์เรย์เป้าหมายและเพิ่มทั้งสามตัวชี้ ( T1, T2เป้าหมาย) หากเพรT1 | T2ดิเคตนั้นจะไม่มีการยกเลิกองค์ประกอบใด ๆ แต่จะมีขนาดเล็กกว่าที่คัดลอกไป กริยาของรูปแบบT1 & ¬T2นอกจากนี้ยังสามารถดำเนินการโดยใช้กลยุทธ์การผสาน แต่¬T1หรือT1 | ¬T2ไม่สามารถ

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

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

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

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

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