אפליקציות רבות שולחות שאילתות למסד נתונים כדי לאכלס דף יחיד באפליקציות שלהן. באפליקציות כאלה, לא צריך את כל ההתאמות, אלא רק את k ההתאמות המובילות על סמך סדר המיון של האינדקס. אפשר להטמיע את סוג החיפוש הזה בצורה יעילה מאוד באמצעות אינדקסים של חיפושים. בדף הזה מוסבר איך ליצור אינדקס עם התאמה ל-k העליונים ואיך לחפש בו.
יצירת אינדקסים של חיפושים להתאמות k המובילות
כדי להגדיר אינדקס חיפוש להתאמה של k התוצאות המובילות, משתמשים ב-ORDER BY כדי להזמין את אינדקס החיפוש לפי עמודה ספציפית. השאילתות צריכות לכלול פסקה ORDER BY שתואמת בדיוק לסדר המיון של אינדקס החיפוש (כולל כיוון עולה לעומת כיוון יורד) ופסקה LIMIT שמבקשת שהשאילתה תיפסק אחרי מציאת k שורות תואמות.
אפשר גם להטמיע מספור עמודים באמצעות הסעיפים האלה. מידע נוסף זמין במאמר בנושא הגדרת מעברי עמוד בשאילתות חיפוש.
במקרים מסוימים, כדאי לשמור כמה אינדקסים של חיפוש שממוינים לפי עמודות שונות. בדומה לחלוקה למחיצות, יש כאן איזון בין עלות האחסון והכתיבה לבין זמן האחזור של השאילתה.
לדוגמה, נניח שיש טבלה עם הסכימה הבאה:
GoogleSQL
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
RecordTimestamp INT64 NOT NULL,
ReleaseTimestamp INT64 NOT NULL,
ListenTimestamp INT64 NOT NULL,
AlbumTitle STRING(MAX),
AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN
) PRIMARY KEY(AlbumId);
CREATE SEARCH INDEX AlbumsRecordTimestampIndex
ON Albums(AlbumTitle_Tokens, SingerId_Tokens)
STORING (ListenTimestamp)
ORDER BY RecordTimestamp DESC
CREATE SEARCH INDEX AlbumsReleaseTimestampIndex
ON Albums(AlbumTitle_Tokens)
STORING (ListenTimestamp)
ORDER BY ReleaseTimestamp DESC
PostgreSQL
CREATE TABLE albums (
albumid character varying NOT NULL,
recordtimestamp bigint NOT NULL,
releasetimestamp bigint NOT NULL,
listentimestamp bigint NOT NULL,
albumtitle character varying,
albumtitle_tokens spanner.tokenlist
GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));
CREATE SEARCH INDEX albumsrecordtimestampindex
ON Albums(albumtitle_tokens, singerid_tokens)
INCLUDE (listentimestamp)
ORDER BY recordtimestamp DESC
CREATE SEARCH INDEX albumsreleasetimestampindex
ON Albums(albumtitle_tokens)
INCLUDE (listentimestamp)
ORDER BY releasetimestamp DESC
חיפוש באינדקסים של שאילתות כדי למצוא את k ההתאמות המובילות
כמו שצוין קודם, השאילתות צריכות לכלול פסקה ORDER BY שתואמת בדיוק לסדר המיון של אינדקס החיפוש (כולל כיוון המיון – עולה או יורד) ופסקה LIMIT שמבקשת שהשאילתה תיפסק אחרי שהמערכת תמצא k שורות תואמות.
ברשימה הבאה מנותחת היעילות של כמה שאילתות נפוצות.
השאילתה הזו יעילה מאוד. הוא בוחר את האינדקס
AlbumsRecordTimestampIndex. גם אם יש הרבה אלבומים עם המילה happy, השאילתה סורקת רק מספר קטן של שורות:GoogleSQL
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, 'happy') ORDER BY RecordTimestamp DESC LIMIT 10PostgreSQL
SELECT albumid FROM albums WHERE spanner.search(albumtitle_tokens, 'happy') ORDER BY recordtimestamp DESC LIMIT 10אותה שאילתה, שמבקשת סדר מיון לפי
ReleaseTimestampבסדר יורד, משתמשת באינדקסAlbumsReleaseTimestampIndexוהיא יעילה באותה מידה:GoogleSQL
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, 'happy') ORDER BY ReleaseTimestamp DESC LIMIT 10PostgreSQL
SELECT albumid FROM albums WHERE spanner.search(albumtitle_tokens, 'happy') ORDER BY releasetimestamp DESC LIMIT 10שאילתה שמבקשת סדר מיון לפי
ListenTimestampלא מבצעת שאילתת top-k ביעילות. הפונקציה צריכה לאחזר את כל האלבומים התואמים, למיין אותם לפיListenTimestamp,ולהחזיר את 10 האלבומים הראשונים. שאילתה כזו צורכת יותר משאבים אם יש מספר גדול של מסמכים שמכילים את המונח 'happy'.GoogleSQL
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, 'happy') ORDER BY ListenTimestamp DESC LIMIT 10PostgreSQL
SELECT albumid FROM albums WHERE spanner.search(albumtitle_tokens, 'happy') ORDER BY listentimestamp DESC LIMIT 10באופן דומה, שאילתה לא תפעל ביעילות אם היא מבקשת שהתוצאות יסודרו לפי העמודה
RecordTimestampבסדר עולה. הוא סורק את כל השורות עם המילה happy, למרות שישLIMIT.GoogleSQL
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, 'happy') ORDER BY RecordTimestamp ASC LIMIT 10PostgreSQL
SELECT albumid FROM albums WHERE spanner.search(albumtitle_tokens, 'happy') ORDER BY recordtimestamp ASC LIMIT 10
המאמרים הבאים
- מידע נוסף על שאילתות חיפוש בטקסט מלא
- איך לדרג את תוצאות החיפוש
- איך מחלקים את תוצאות החיפוש לדפים
- איך משלבים שאילתות של טקסט מלא עם שאילתות של טקסט חלקי
- איך מחפשים בכמה עמודות