PostgreSQL рдореЗрдВ рд╕реВрдЪрдХрд╛рдВрдХ - 8 (RUM)

рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА PostgreSQL рдЗрдВрдбреЗрдХреНрд╕рд┐рдВрдЧ рдЗрдВрдЬрди , рдПрдХреНрд╕реЗрд╕ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдФрд░ рдореБрдЦреНрдп рдПрдХреНрд╕реЗрд╕ рд╡рд┐рдзрд┐рдпреЛрдВ, рдЬреИрд╕реЗ: рд╣реИрд╢ рдЗрдВрдбреЗрдХреНрд╕ , рдмреА- рдЯреНрд░реАрдЬрд╝ , рдЬреАрдПрд╕рдЯреА , рдПрд╕рдкреА-рдЬреАрдПрд╕рдЯреА , рдФрд░ рдЬреАрдЖрдИрдПрди рдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рд╣реИ ред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдЬрд┐рди рдХреИрд╕реЗ рд░рдо рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИред

рд░рдо


рд╣рд╛рд▓рд╛рдВрдХрд┐ рд▓реЗрдЦрдХреЛрдВ рдХрд╛ рджрд╛рд╡рд╛ рд╣реИ рдХрд┐ рдЬрд┐рди рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЬрд┐рдиреНрди рд╣реИ, рдкреЗрдп рдХрд╛ рд╡рд┐рд╖рдп рдЕрдВрддрддрдГ рдЬреАрдд рдЧрдпрд╛ рд╣реИ: рдЕрдЧрд▓реА рдкреАрдврд╝реА рдХреЗ рдЬрд┐рди рдХреЛ RUM рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИред

рдпрд╣ рдкрд╣реБрдВрдЪ рд╡рд┐рдзрд┐ GIN рдХреЛ рд╕рдордЭрдиреЗ рд╡рд╛рд▓реА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рд╡рд┐рд╕реНрддреГрдд рдХрд░рддреА рд╣реИ рдФрд░ рд╣рдореЗрдВ рдкреВрд░реНрдг-рдкрд╛рда рдЦреЛрдЬ рдХреЛ рдФрд░ рднреА рддреЗрдЬ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддреА рд╣реИред рд▓реЗрдЦреЛрдВ рдХреА рдЗрд╕ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ, рдпрд╣ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рд╣реИ рдЬреЛ рдорд╛рдирдХ PostgreSQL рд╡рд┐рддрд░рдг рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИ рдФрд░ рдПрдХ рдмрд╛рд╣рд░реА рд╡рд┐рд╕реНрддрд╛рд░ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрдИ рдЗрдВрд╕реНрдЯреЙрд▓реЗрд╢рди рд╡рд┐рдХрд▓реНрдк рдЙрдкрд▓рдмреНрдз рд╣реИрдВ:

  • PGDG рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ "yum" рдпрд╛ "apt" рдкреИрдХреЗрдЬ рд▓реЗрдВ ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдкрдиреЗ "рдкреЛрд╕реНрдЯрдЧреНрд░реИрд╕рд┐рдХрд▓ -10" рдкреИрдХреЗрдЬ рд╕реЗ рдкреЛрд╕реНрдЯрдЧреНрд░реЗрд╕реАрдХреНрдпреВрдПрд▓ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рд╣реИ, рддреЛ "рдкреЛрд╕реНрдЯрдЧреНрд░реИрдХреНрдХрд▓ -10-рд░рдо" рднреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВред
  • рдЬреАрдердм рдкрд░ рд╕реНрд░реЛрдд рдХреЛрдб рд╕реЗ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВ рдФрд░ рдЕрдкрдиреЗ рджрдо рдкрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ (рдирд┐рд░реНрджреЗрд╢ рд╡рд╣рд╛рдВ рднреА рд╣реИ)ред
  • рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рдкреНрд░реЛ рдПрдВрдЯрд░рдкреНрд░рд╛рдЗрдЬ рдХреЗ рдПрдХ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ (рдпрд╛ рдХрдо рд╕реЗ рдХрдо рд╡рд╣рд╛рдВ рд╕реЗ рдкреНрд░рд▓реЗрдЦрди рдкрдврд╝реЗрдВ)ред

рдЬрд┐рди рдХреА рд╕реАрдорд╛рдПрдБ


GIN рдХреА рдХреМрди рд╕реА рд╕реАрдорд╛рдПрдБ рд╣рдореЗрдВ RUM рдХреЛ рдкрд╛рд░ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддреА рд╣реИрдВ?

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, "tsvector" рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рди рдХреЗрд╡рд▓ lexemes рд╣реЛрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ рдЕрдВрджрд░ рдЙрдирдХреЗ рдкрджреЛрдВ рдкрд░ рднреА рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрддреА рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдкрд┐рдЫрд▓реА рдмрд╛рд░ рджреЗрдЦрд╛ рдерд╛ , GIN рд╕реВрдЪрдХрд╛рдВрдХ рдЗрд╕ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ, рд╡рд╛рдХреНрдпрд╛рдВрд╢реЛрдВ рдХреА рдЦреЛрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдСрдкрд░реЗрд╢рди, рдЬреЛ рд╕рдВрд╕реНрдХрд░рдг 9.6 рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, GIN рд╕реВрдЪрдХрд╛рдВрдХ рджреНрд╡рд╛рд░рд╛ рдЕрдХреНрд╖рдо рд░реВрдк рд╕реЗ рд╕рдорд░реНрдерд┐рдд рд╣реИрдВ рдФрд░ рд░реАрдЪреЗрдХ рдХреЗ рд▓рд┐рдП рдореВрд▓ рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪрдирд╛ рд╣реИред

рджреВрд╕рд░рд╛, рдЦреЛрдЬ рдкреНрд░рдгрд╛рд▓рд┐рдпрд╛рдВ рдЖрдорддреМрд░ рдкрд░ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХрддрд╛ (рдЬреЛ рдХреБрдЫ рднреА рдорддрд▓рдм рд╣реИ) рджреНрд╡рд╛рд░рд╛ рдЫрд╛рдВрдЯреЗ рдЧрдП рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрд╛рддреА рд╣реИрдВред рд╣рдо рд░реИрдВрдХрд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди "ts_rank" рдФрд░ "ts_rank_cd" рдХрд╛ рдЙрдкрдпреЛрдЧ рдЗрд╕ рдЕрдВрдд рддрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ рдкрд░рд┐рдгрд╛рдо рдХреА рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдЧрдгрдирд╛ рдХрд░рдиреА рд╣реЛрдЧреА, рдЬреЛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдзреАрдореА рд╣реИред

рдкрд╣рд▓реЗ рд╕рдиреНрдирд┐рдХрдЯрди рдХреЗ рд▓рд┐рдП, RUM рдкрд╣реБрдВрдЪ рд╡рд┐рдзрд┐ рдХреЛ GIN рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рд░реВрдк рд╕реЗ рд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдЖрд╡рд╢реНрдпрдХ рдХреНрд░рдо рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ (рдЬреИрд╕реЗ GiST рдирд┐рдХрдЯрддрдо рдкрдбрд╝реЛрд╕рд┐рдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ)ред рдХрджрдо рд╕реЗ рдХрджрдо рдорд┐рд▓рд╛рдХрд░ рдЪрд▓рддреЗ рд╣реИрдВред

рд╡рд╛рдХреНрдпрд╛рдВрд╢реЛрдВ рдХреА рдЦреЛрдЬ


рдПрдХ рдкреВрд░реНрдг-рдкрд╛рда рдЦреЛрдЬ рдХреНрд╡реЗрд░реА рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рдСрдкрд░реЗрдЯрд░ рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд▓реЗрдХреНрд╕реЗрдо рдХреЗ рдмреАрдЪ рдХреА рджреВрд░реА рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдЙрди рджрд╕реНрддрд╛рд╡реЗрдЬреЛрдВ рдХреЛ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдирдореЗрдВ "рд╣рд╛рде" рдХреЛ "рдЬрд╛рдВрдШ" рд╕реЗ рджреЛ рдФрд░ рд╢рдмреНрджреЛрдВ рдХреЗ рд╕рд╛рде рдЕрд▓рдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

postgres=# select to_tsvector('Clap your hands, slap your thigh') @@ to_tsquery('hand <3> thigh'); 
  ?column? ---------- t (1 row) 

рдпрд╛ рд╣рдо рд╕рдВрдХреЗрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╢рдмреНрджреЛрдВ рдХреЛ рдПрдХ рдХреЗ рдмрд╛рдж рдПрдХ рд╕реНрдерд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:

 postgres=# select to_tsvector('Clap your hands, slap your thigh') @@ to_tsquery('hand <-> slap'); 
  ?column? ---------- t (1 row) 

рдирд┐рдпрдорд┐рдд GIN рдЗрдВрдбреЗрдХреНрд╕ рдЙрди рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рдирдореЗрдВ рджреЛрдиреЛрдВ рд▓реЗрдХреНрдореЗрдореНрд╕ рд╣реЛрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдХреЗрд╡рд▓ tvvector рдореЗрдВ рджреЗрдЦ рдХрд░ рдЙрдирдХреЗ рдмреАрдЪ рдХреА рджреВрд░реА рдХреА рдЬрд╛рдБрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 postgres=# select to_tsvector('Clap your hands, slap your thigh'); 
  to_tsvector -------------------------------------- 'clap':1 'hand':3 'slap':4 'thigh':6 (1 row) 

RUM рдЗрдВрдбреЗрдХреНрд╕ рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ lexeme рдХреЗрд╡рд▓ рддрд╛рд▓рд┐рдХрд╛ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ: рдкреНрд░рддреНрдпреЗрдХ TID рдХреЛ рдЙрди рдкрджреЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рд╕рд╛рде рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдореЗрдВ lexeme рд╣реЛрддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╣рдо "рд╕реНрд▓рд┐рдЯ-рд╢реАрдЯ" рдЯреЗрдмрд▓ рдкрд░ рдмрдирд╛рдП рдЧрдП рд╕реВрдЪрдХрд╛рдВрдХ рдХреА рдкрд░рд┐рдХрд▓реНрдкрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХрд╛рдлреА рдкрд░рд┐рдЪрд┐рдд рд╣реИ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ tsvector рдХреЗ рд▓рд┐рдП рдСрдкрд░реЗрдЯрд░ рд░реВрдо рдХрд╛ рдЙрдкрдпреЛрдЧ "рд░рдо_рд╕реИрдХреНрдЯрд░_рдЯреЙрдк"):

 postgres=# create extension rum; postgres=# create index on ts using rum(doc_tsv); 




рдЖрдХреГрддрд┐ рдореЗрдВ рдЧреНрд░реЗ рд╡рд░реНрдЧ рдореЗрдВ рд╕реНрдерд┐рддрд┐ рдЬрд╛рдирдХрд╛рд░реА рд╢рд╛рдорд┐рд▓ рд╣реИ:

 postgres=# select ctid, left(doc,20), doc_tsv from ts; 
  ctid | left | doc_tsv -------+----------------------+--------------------------------------------------------- (0,1) | Can a sheet slitter | 'sheet':3,6 'slit':5 'slitter':4 (0,2) | How many sheets coul | 'could':4 'mani':2 'sheet':3,6 'slit':8 'slitter':7 (0,3) | I slit a sheet, a sh | 'sheet':4,6 'slit':2,8 (1,1) | Upon a slitted sheet | 'sheet':4 'sit':6 'slit':3 'upon':1 (1,2) | Whoever slit the she | 'good':7 'sheet':4,8 'slit':2 'slitter':9 'whoever':1 (1,3) | I am a sheet slitter | 'sheet':4 'slitter':5 (2,1) | I slit sheets. | 'sheet':3 'slit':2 (2,2) | I am the sleekest sh | 'ever':8 'sheet':5,10 'sleekest':4 'slit':9 'slitter':6 (2,3) | She slits the sheet | 'sheet':4 'sit':6 'slit':2 (9 rows) 

рдЬрдм "рдлрд╛рд╕реНрдЯрдЕрдкрдбреЗрдЯ" рдкреИрд░рд╛рдореАрдЯрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдЬреАрдЖрдИрдПрди рдПрдХ рд╕реНрдердЧрд┐рдд рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рднреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ; рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ RUM рд╕реЗ рдирд┐рдХрд╛рд▓ рджреА рдЧрдИ рд╣реИред

рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╕реВрдЪрдХрд╛рдВрдХ рд▓рд╛рдЗрд╡ рдбреЗрдЯрд╛ рдкрд░ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЪрд▓реЛ pgsql-hackers рдореЗрд▓рд┐рдВрдЧ рд╕реВрдЪреА рдХреЗ рдкрд░рд┐рдЪрд┐рдд рд╕рдВрдЧреНрд░рд╣ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

 fts=# alter table mail_messages add column tsv tsvector; fts=# set default_text_search_config = default; fts=# update mail_messages set tsv = to_tsvector(body_plain); 
 ... UPDATE 356125 

рдпрд╣ рдХреИрд╕реЗ рдПрдХ рд╡рд╛рдХреНрдпрд╛рдВрд╢ рд╣реИ рдЬреЛ рд╡рд╛рдХреНрдпрд╛рдВрд╢реЛрдВ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ GIN рд╕реВрдЪрдХрд╛рдВрдХ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 fts=# create index tsv_gin on mail_messages using gin(tsv); fts=# explain (costs off, analyze) select * from mail_messages where tsv @@ to_tsquery('hello <-> hackers'); 
  QUERY PLAN --------------------------------------------------------------------------------- Bitmap Heap Scan on mail_messages (actual time=2.490..18.088 rows=259 loops=1) Recheck Cond: (tsv @@ to_tsquery('hello <-> hackers'::text)) Rows Removed by Index Recheck: 1517 Heap Blocks: exact=1503 -> Bitmap Index Scan on tsv_gin (actual time=2.204..2.204 rows=1776 loops=1) Index Cond: (tsv @@ to_tsquery('hello <-> hackers'::text)) Planning time: 0.266 ms Execution time: 18.151 ms (8 rows) 

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдпреЛрдЬрдирд╛ рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, GIN рдЗрдВрдбреЗрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ 1776 рд╕рдВрднрд╛рд╡рд┐рдд рдореИрдЪ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ 259 рдмрдЪреЗ рд╣реИрдВ рдФрд░ 1517 рдХреЛ рд░реАрдЪреЗрдХ рд╕реНрдЯреЗрдЬ рдкрд░ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

GIN рдЗрдВрдбреЗрдХреНрд╕ рдХреЛ рдбрд┐рд▓реАрдЯ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ RUM рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╣реИрдВред

 fts=# drop index tsv_gin; fts=# create index tsv_rum on mail_messages using rum(tsv); 

рд╕реВрдЪрдХрд╛рдВрдХ рдореЗрдВ рдЕрдм рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рд╢рд╛рдорд┐рд▓ рд╣реИ, рдФрд░ рдЦреЛрдЬ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ рдХреА рдЧрдИ рд╣реИ:

 fts=# explain (costs off, analyze) select * from mail_messages where tsv @@ to_tsquery('hello <-> hackers'); 
  QUERY PLAN -------------------------------------------------------------------------------- Bitmap Heap Scan on mail_messages (actual time=2.798..3.015 rows=259 loops=1) Recheck Cond: (tsv @@ to_tsquery('hello <-> hackers'::text)) Heap Blocks: exact=250 -> Bitmap Index Scan on tsv_rum (actual time=2.768..2.768 rows=259 loops=1) Index Cond: (tsv @@ to_tsquery('hello <-> hackers'::text)) Planning time: 0.245 ms Execution time: 3.053 ms (7 rows) 

рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХрддрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЫрдВрдЯрдиреА


рдЖрд╡рд╢реНрдпрдХ рдХреНрд░рдо рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рджрд╕реНрддрд╛рд╡реЗрдЬреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрд░рдпреВрдПрдо рдЗрдВрдбреЗрдХреНрд╕ рдСрд░реНрдбрд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреА рд╣рдордиреЗ рдЬреАрдПрд╕рдЯреА рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд▓реЗрдЦ рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдереАред RUM рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдРрд╕реЗ рдСрдкрд░реЗрдЯрд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ, <=> , рдЬреЛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ ("tsvector") рдФрд░ рдХреНрд╡реЗрд░реА ("tsquery") рдХреЗ рдмреАрдЪ рдХреБрдЫ рджреВрд░реА рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

 fts=# select to_tsvector('Can a sheet slitter slit sheets?') <=&gtl to_tsquery('slit'); 
  ?column? ---------- 16.4493 (1 row) 
 fts=# select to_tsvector('Can a sheet slitter slit sheets?') <=> to_tsquery('sheet'); 
  ?column? ---------- 13.1595 (1 row) 

рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдкрд╣рд▓реА рдХреНрд╡реЗрд░реА рд╕реЗ рджреВрд╕рд░реЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ: рдЬрд┐рддрдирд╛ рдЕрдзрд┐рдХ рдмрд╛рд░ рдпрд╣ рд╢рдмреНрдж рд╣реЛрддрд╛ рд╣реИ, рдЙрддрдирд╛ рд╣реА рдХрдо "рдореВрд▓реНрдпрд╡рд╛рди" рд╣реЛрддрд╛ рд╣реИред

рдЖрдЗрдП рдлрд┐рд░ рд╕реЗ GIN рдФрд░ RUM рдХреА рддреБрд▓рдирд╛ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдмрдбрд╝реЗ рдбреЗрдЯрд╛ рд╕рд╛рдЗрдЬрд╝ рдкрд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ: рд╣рдо "рд╣реИрд▓реЛ" рдФрд░ "рд╣реИрдХрд┐рдВрдЧ" рд╡рд╛рд▓реЗ рджрд╕ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВрдЧреЗред

 fts=# explain (costs off, analyze) select * from mail_messages where tsv @@ to_tsquery('hello & hackers') order by ts_rank(tsv,to_tsquery('hello & hackers')) limit 10; 
  QUERY PLAN --------------------------------------------------------------------------------------------- Limit (actual time=27.076..27.078 rows=10 loops=1) -> Sort (actual time=27.075..27.076 rows=10 loops=1) Sort Key: (ts_rank(tsv, to_tsquery('hello & hackers'::text))) Sort Method: top-N heapsort Memory: 29kB -> Bitmap Heap Scan on mail_messages (actual ... rows=1776 loops=1) Recheck Cond: (tsv @@ to_tsquery('hello & hackers'::text)) Heap Blocks: exact=1503 -> Bitmap Index Scan on tsv_gin (actual ... rows=1776 loops=1) Index Cond: (tsv @@ to_tsquery('hello & hackers'::text)) Planning time: 0.276 ms Execution time: 27.121 ms (11 rows) 

GIN рдЗрдВрдбреЗрдХреНрд╕ 1776 рдореИрдЪ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдЬреЛ рддрдм рджрд╕ рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда рд╣рд┐рдЯ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдХрджрдо рдХреЗ рд░реВрдк рдореЗрдВ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

RUM рдЗрдВрдбреЗрдХреНрд╕ рдХреЗ рд╕рд╛рде, рдХреНрд╡реЗрд░реА рдХреЛ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЗрдВрдбреЗрдХреНрд╕ рд╕реНрдХреИрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рдХрд┐рд╕реА рднреА рдЕрддрд┐рд░рд┐рдХреНрдд рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд╣реАрдВ рджреЗрдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЕрд▓рдЧ рд╕реЗ рдЫрдВрдЯрд╛рдИ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ:

 fts=# explain (costs off, analyze) select * from mail_messages where tsv @@ to_tsquery('hello & hackers') order by tsv <=> to_tsquery('hello & hackers') limit 10; 
  QUERY PLAN -------------------------------------------------------------------------------------------- Limit (actual time=5.083..5.171 rows=10 loops=1) -> Index Scan using tsv_rum on mail_messages (actual ... rows=10 loops=1) Index Cond: (tsv @@ to_tsquery('hello & hackers'::text)) Order By: (tsv <=> to_tsquery('hello & hackers'::text)) Planning time: 0.244 ms Execution time: 5.207 ms (6 rows) 

рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА


рдЖрд░рдпреВрдПрдо рдЗрдВрдбреЗрдХреНрд╕, рд╕рд╛рде рд╣реА рдЬреАрдЖрдИрдПрди, рдХрдИ рдХреНрд╖реЗрддреНрд░реЛрдВ рдкрд░ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЬрдм GIN рджреВрд╕рд░реЗ рдХреЙрд▓рдо рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓рдо рд╕реЗ рд▓реЗрдХреНрд╕рдо рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рддрд╛ рд╣реИ, RUM рд╣рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЗ рд╕рд╛рде рдореБрдЦреНрдп рдХреНрд╖реЗрддреНрд░ ("tsvector") рдХреЛ "рд╕рдВрдмрджреНрдз" рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдСрдкрд░реЗрдЯрд░ рд╡рд░реНрдЧ "rum_tsvector_addon_ops" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

 fts=# create index on mail_messages using rum(tsv RUM_TSVECTOR_ADDON_OPS, sent) WITH (ATTACH='sent', TO='tsv'); 

рдЕрддрд┐рд░рд┐рдХреНрдд рдХреНрд╖реЗрддреНрд░ рдкрд░ рдЫрдВрдЯреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рдЗрд╕ рд╕реВрдЪрдХрд╛рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 fts=# select id, sent, sent <=> '2017-01-01 15:00:00' from mail_messages where tsv @@ to_tsquery('hello') order by sent <=> '2017-01-01 15:00:00' limit 10; 
  id | sent | ?column? ---------+---------------------+---------- 2298548 | 2017-01-01 15:03:22 | 202 2298547 | 2017-01-01 14:53:13 | 407 2298545 | 2017-01-01 13:28:12 | 5508 2298554 | 2017-01-01 18:30:45 | 12645 2298530 | 2016-12-31 20:28:48 | 66672 2298587 | 2017-01-02 12:39:26 | 77966 2298588 | 2017-01-02 12:43:22 | 78202 2298597 | 2017-01-02 13:48:02 | 82082 2298606 | 2017-01-02 15:50:50 | 89450 2298628 | 2017-01-02 18:55:49 | 100549 (10 rows) 

рдпрд╣рд╛рдВ рд╣рдо рдЙрди рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЗ рдорд┐рд▓рд╛рди рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рддрд┐рдерд┐ рдХреЗ рдХрд░реАрдм рд╣реИрдВ, рдкрд╣рд▓реЗ рдпрд╛ рдмрд╛рдж рдореЗрдВ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ред рдирд┐рд░реНрджрд┐рд╖реНрдЯ рддрд╛рд░реАрдЦ рд╕реЗ рдкрд╣рд▓реЗ (рдпрд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд) рд╕рдЦреНрддреА рд╕реЗ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ <=| рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдпрд╛ |=> ) рдСрдкрд░реЗрдЯрд░ред

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВ, рдХреНрд╡реЗрд░реА рдХреЗрд╡рд▓ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЗрдВрдбреЗрдХреНрд╕ рд╕реНрдХреИрди рджреНрд╡рд╛рд░рд╛ рдХреА рдЬрд╛рддреА рд╣реИ:

 ts=# explain (costs off) select id, sent, sent <=> '2017-01-01 15:00:00' from mail_messages where tsv @@ to_tsquery('hello') order by sent <=> '2017-01-01 15:00:00' limit 10; 
  QUERY PLAN --------------------------------------------------------------------------------- Limit -> Index Scan using mail_messages_tsv_sent_idx on mail_messages Index Cond: (tsv @@ to_tsquery('hello'::text)) Order By: (sent <=> '2017-01-01 15:00:00'::timestamp without time zone) (4 rows) 

рдпрджрд┐ рд╣рдордиреЗ рдлрд╝реАрд▓реНрдб рдПрд╕реЛрд╕рд┐рдПрд╢рди рдкрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рдмрд┐рдирд╛ рдЗрдВрдбреЗрдХреНрд╕ рдмрдирд╛рдпрд╛ рд╣реИ, рддреЛ рдПрдХ рд╕рдорд╛рди рдХреНрд╡реЗрд░реА рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЗрдВрдбреЗрдХреНрд╕ рд╕реНрдХреИрди рдХреЗ рд╕рднреА рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рд╕реЙрд░реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рддрд┐рдерд┐ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЕрдиреНрдп рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ RUM рд╕реВрдЪрдХрд╛рдВрдХ рдореЗрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд╕реНрддреБрддрдГ рд╕рднреА рдЖрдзрд╛рд░ рдкреНрд░рдХрд╛рд░ рд╕рдорд░реНрдерд┐рдд рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдСрдирд▓рд╛рдЗрди рд╕реНрдЯреЛрд░ рддреЗрдЬрд╝реА рд╕реЗ рдирд╡реАрдирддрд╛ (рджрд┐рдирд╛рдВрдХ), рдореВрд▓реНрдп (рд╕рдВрдЦреНрдпрд╛рддреНрдордХ) рдФрд░ рд▓реЛрдХрдкреНрд░рд┐рдпрддрд╛ рдпрд╛ рдЫреВрдЯ рдореВрд▓реНрдп (рдкреВрд░реНрдгрд╛рдВрдХ рдпрд╛ рдлреНрд▓реЛрдЯрд┐рдВрдЧ-рдкреЙрдЗрдВрдЯ) рджреНрд╡рд╛рд░рд╛ рдорд╛рд▓ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдЕрдиреНрдп рдСрдкрд░реЗрдЯрд░ рдХрдХреНрд╖рд╛рдПрдВ


рддрд╕реНрд╡реАрд░ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдЕрдиреНрдп рдСрдкрд░реЗрдЯрд░ рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЪрд▓реЛ "rum_tsvector_hash_ops" рдФрд░ "rum_tsvector_hash_addon_ops" рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ ред рд╡реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЪрд░реНрдЪрд╛ рдХрд┐рдП рдЧрдП "рд░реБрдо_рд╕реЗрдЯрд░рд╡реЙрдЯрд░_рдУрдкреНрд╕" рдФрд░ "рд░реБрдорд╡реНрд╕рдЯреНрд░рдХреНрдЯрд░_рдЖрдбреЗрди_рдУрдкреНрд╕" рдХреЗ рд╕рдорд╛рди рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрдВрдбреЗрдХреНрд╕ рд▓реЗрдХреНрд╕реЗрдо рдХреЗ рдмрдЬрд╛рдп рд▓реЗрдХреНрд╕рдо рдХреЗ рд╣реИрд╢ рдХреЛрдб рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд╕реВрдЪрдХрд╛рдВрдХ рдЖрдХрд╛рд░ рдХреЛ рдХрдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЦреЛрдЬ рдХрдо рд╕рдЯреАрдХ рд╣реЛ рдЬрд╛рддреА рд╣реИ рдФрд░ рдкреБрди: рдЬрд╛рдВрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕реВрдЪрдХрд╛рдВрдХ рдЕрдм рдЖрдВрд╢рд┐рдХ рдореИрдЪ рдХреА рдЦреЛрдЬ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ "rum_tsquery_ops" рдСрдкрд░реЗрдЯрд░ рд╡рд░реНрдЧ рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдПред рдпрд╣ рд╣рдореЗрдВ "рдЙрд▓рдЯрд╛" рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддрд╛ рд╣реИ: рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдвреВрдВрдвреЗрдВред рдЗрд╕рдХреА рдЬрд░реВрд░рдд рдХреНрдпреЛрдВ рдкрдбрд╝ рд╕рдХрддреА рд╣реИ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрдкрдиреЗ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдпрд╛ рдирдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╡рд░реНрдЧреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдирдП рдорд╛рд▓ рдХреА рд╕рджрд╕реНрдпрддрд╛ рдХреЗ рд▓рд┐рдПред рдЗрд╕ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдХреЛ рджреЗрдЦреЗрдВ:

 fts=# create table categories(query tsquery, category text); fts=# insert into categories values (to_tsquery('vacuum | autovacuum | freeze'), 'vacuum'), (to_tsquery('xmin | xmax | snapshot | isolation'), 'mvcc'), (to_tsquery('wal | (write & ahead & log) | durability'), 'wal'); fts=# create index on categories using rum(query); fts=# select array_agg(category) from categories where to_tsvector( 'Hello hackers, the attached patch greatly improves performance of tuple freezing and also reduces size of generated write-ahead logs.' ) @@ query; 
  array_agg -------------- {vacuum,wal} (1 row) 

рд╢реЗрд╖ рд╕рдВрдЪрд╛рд▓рдХ рд╡рд░реНрдЧ "rum_anyarray_ops" рдФрд░ "rum_anyarray_addon_ops" рдХреЛ "tsvector" рдХреЗ рдмрдЬрд╛рдп рд╕рд░рдгрд┐рдпреЛрдВ рдореЗрдВ рд╣реЗрд░рдлреЗрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рдкрд┐рдЫрд▓реА рдмрд╛рд░ GIN рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЪрд░реНрдЪрд╛ рдореЗрдВ рдерд╛ рдФрд░ рдЗрд╕реЗ рджреЛрд╣рд░рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рд╕реВрдЪрдХрд╛рдВрдХ рдХреЗ рдЖрдХрд╛рд░ рдФрд░ рд░рд╛рдЗрдЯ-рдлреЙрд░рд╡рд░реНрдб рд▓реЙрдЧ (рд╡рд╛рд▓)


рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдЪреВрдВрдХрд┐ RUM GIN рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рдмрдбрд╝рд╛ рдЖрдХрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рдо рдкрд┐рдЫрд▓реА рдмрд╛рд░ рд╡рд┐рднрд┐рдиреНрди рдЗрдВрдбреЗрдХреНрд╕ рдХреЗ рдЖрдХрд╛рд░ рдХреА рддреБрд▓рдирд╛ рдХрд░ рд░рд╣реЗ рдереЗ; рдЖрдЗрдП рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ RUM рдЬреЛрдбрд╝реЗрдВ:

  rum | gin | gist | btree --------+--------+--------+-------- 457 MB | 179 MB | 125 MB | 546 MB 

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдХрд╛рд░ рдореЗрдВ рдХрд╛рдлреА рд╡реГрджреНрдзрд┐ рд╣реБрдИ, рдЬреЛ рдХрд┐ рддреЗрдЬреА рд╕реЗ рдЦреЛрдЬ рдХреА рд▓рд╛рдЧрдд рд╣реИред

рдпрд╣ рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рдмрд┐рдВрджреБ рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ: рдЖрд░рдпреВрдПрдо рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╣реИ, рдЕрд░реНрдерд╛рдд, рдЗрд╕реЗ рд╕рд┐рд╕реНрдЯрдо рдХреЛрд░ рдореЗрдВ рдХрд┐рд╕реА рднреА рд╕рдВрд╢реЛрдзрди рдХреЗ рдмрд┐рдирд╛ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╕рд┐рдХрдВрджрд░ рдХреЛрд░реЛрдЯрдХреЛрд╡ рджреНрд╡рд╛рд░рд╛ рдПрдХ рдкреИрдЪ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж 9.6 рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╕рдХреНрд╖рдо рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рдереА рдХрд┐ рд▓реЙрдЧ рд░рд┐рдХреЙрд░реНрдбреНрд╕ рдХреА рдкреАрдврд╝реАред рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓реЙрдЧрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рддрдХрдиреАрдХ рдмрд┐рд▓реНрдХреБрд▓ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП, рдЗрд╕ рд░рд╕реЛрдИ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рдирд╣реАрдВ рд╣реЛрдиреЗ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓реЙрдЧ рд░рд┐рдХреЙрд░реНрдб рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдирд┐рдореНрди рд╕реНрдерд╛рди рдкрд░ рд╣реИ: рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдХреЛрдб рдкреГрд╖реНрда рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдЗрд░рд╛рджреЗ рдХреЛ рдмрддрд╛рддрд╛ рд╣реИ, рдЗрд╕рдореЗрдВ рдХреЛрдИ рднреА рдмрджрд▓рд╛рд╡ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рд╕рд┐рд╕реНрдЯрдо рдХреЛрд░ рд╣реИ, рдЬреЛ рдкреЗрдЬ рдХреЗ рдкреБрд░рд╛рдиреЗ рдФрд░ рдирдП рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрд╡рд╢реНрдпрдХ рд▓реЙрдЧ рд░рд┐рдХреЙрд░реНрдб рдмрдирд╛рддрд╛ рд╣реИред

рд╡рд░реНрддрдорд╛рди рд▓реЙрдЧ рдЬрдирд░реЗрд╢рди рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдмрд╛рдЗрдЯ рджреНрд╡рд╛рд░рд╛ рдкреГрд╖реНрдареЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рддрд╛ рд╣реИ, рдЕрдкрдбреЗрдЯ рдХрд┐рдП рдЧрдП рдЕрдВрд╢реЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рддрд╛ рд╣реИ, рдФрд░ рдЗрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдЯреБрдХрдбрд╝реЗ рдХреЛ рд▓реЙрдЧ рдХрд░рддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рдкреГрд╖реНрда рдкреНрд░рд╛рд░рдВрдн рд╕реЗ рдЗрд╕рдХреА рднрд░рдкрд╛рдИ рдХрд░рддрд╛ рд╣реИред рдХреЗрд╡рд▓ рдХрдИ рдмрд╛рдЗрдЯреНрд╕ рдпрд╛ рдкреВрд░реЗ рдкреГрд╖реНрда рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╕рдордп рдпрд╣ рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╣рдо рдПрдХ рдкреГрд╖реНрда рдХреЗ рдЕрдВрджрд░ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдмрд╛рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдиреАрдЪреЗ рд▓реЗ рдЬрд╛рдирд╛ (рдпрд╛ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдПрдХ рдЯреБрдХрдбрд╝рд╛ рдирд┐рдХрд╛рд▓реЗрдВ, рд╕рд╛рдордЧреНрд░реА рдХреЛ рдКрдкрд░ рд▓реЗ рдЬрд╛рдирд╛), рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЬреЛрдбрд╝реЗ рдпрд╛ рд╣рдЯрд╛рдП рдЬрд╛рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрд╛рдлреА рдЕрдзрд┐рдХ рдмрд╛рдЗрдЯреНрд╕ рдмрджрд▓ рдЬрд╛рдПрдВрдЧреЗред

рдЗрд╕рдХреЗ рдХрд╛рд░рдг, рдЧрд╣рди рд░реВрдк рд╕реЗ рдмрджрд▓рддреЗ рд╣реБрдП RUM рдЗрдВрдбреЗрдХреНрд╕ GIN рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрд╛рдлреА рдмрдбрд╝реЗ рдЖрдХрд╛рд░ рдХреЗ рд▓реЙрдЧ рд░рд┐рдХреЙрд░реНрдб рдЙрддреНрдкрдиреНрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдЬреЛ рдХрд┐ рд╡рд┐рд╕реНрддрд╛рд░ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдХреЛрд░ рдХрд╛ рдПрдХ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рд▓реЙрдЧ рдХреЛ рдЕрдкрдиреЗ рдЖрдк рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рддрд╛ рд╣реИ)ред рдЗрд╕ рдХрд╖реНрдЯрдкреНрд░рдж рдкреНрд░рднрд╛рд╡ рдХреА рд╕реАрдорд╛ рдмрд╣реБрдд рд╣рдж рддрдХ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рд░реНрдпрднрд╛рд░ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рдПрдХ рдЕрдВрддрд░реНрджреГрд╖реНрдЯрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЪрд▓реЛ рдХрдИ рдмрд╛рд░ рдХрдИ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╣рдЯрд╛рдиреЗ рдФрд░ рдЬреЛрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ "рд╡реИрдХреНрдпреВрдо" рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рд╣рдо рдирд┐рдореНрди рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЙрдЧ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рдЖрдХрд╛рд░ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: рд╢реБрд░реБрдЖрдд рдореЗрдВ рдФрд░ рдЕрдВрдд рдореЗрдВ, "pg_current_wal_location" рдлрд╝рдВрдХреНрд╢рди ("pg_current_xlog_location" рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ "рджрд╕ рд╕реЗ рдЕрдзрд┐рдХ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реЙрдЧ рдореЗрдВ рд╕реНрдерд┐рддрд┐ рдпрд╛рдж рд░рдЦреЗрдВ рдФрд░ рдлрд┐рд░ рдЕрдВрддрд░ рджреЗрдЦреЗрдВред

рд▓реЗрдХрд┐рди рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╣рдореЗрдВ рдпрд╣рд╛рдВ рдХрдИ рдкрд╣рд▓реБрдУрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рд╛рде рдХреЗрд╡рд▓ рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ (рдЕрдиреНрдпрдерд╛, "рдЕрддрд┐рд░рд┐рдХреНрдд" рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдПрдЧрд╛)ред рдпрджрд┐ рдпрд╣ рдорд╛рдорд▓рд╛ рд╣реИ, рддреЛ рд╣рдо рди рдХреЗрд╡рд▓ RUM, рдмрд▓реНрдХрд┐ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдЕрджреНрдпрддрди рдФрд░ рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕реВрдЪрдХрд╛рдВрдХ рдХрд╛ рднреА рдзреНрдпрд╛рди рд░рдЦрддреЗ рд╣реИрдВред рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдорд╛рди рднреА рдЖрдХрд╛рд░ ("рдкреНрд░рддрд┐рдХреГрддрд┐" рд▓реЙрдЧ рд╕реНрддрд░ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдмрд┐рдирд╛ рд╕рдВрдкреАрдбрд╝рди рдХреЗ, рдпрд╣рд╛рдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛)ред рд▓реЗрдХрд┐рди рдЪрд▓реЛ рд╡реИрд╕реЗ рднреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред

 fts=# select pg_current_wal_location() as start_lsn \gset 

 fts=# insert into mail_messages(parent_id, sent, subject, author, body_plain, tsv) select parent_id, sent, subject, author, body_plain, tsv from mail_messages where id % 100 = 0; 
 INSERT 0 3576 

 fts=# delete from mail_messages where id % 100 = 99; 
 DELETE 3590 

 fts=# vacuum mail_messages; 

 fts=# insert into mail_messages(parent_id, sent, subject, author, body_plain, tsv) select parent_id, sent, subject, author, body_plain, tsv from mail_messages where id % 100 = 1; 
 INSERT 0 3605 

 fts=# delete from mail_messages where id % 100 = 98; 
 DELETE 3637 

 fts=# vacuum mail_messages; 

 fts=# insert into mail_messages(parent_id, sent, subject, author, body_plain, tsv) select parent_id, sent, subject, author, body_plain, tsv from mail_messages where id % 100 = 2; 
 INSERT 0 3625 

 fts=# delete from mail_messages where id % 100 = 97; 
 DELETE 3668 

 fts=# vacuum mail_messages; 

 fts=# select pg_current_wal_location() as end_lsn \gset fts=# select pg_size_pretty(:'end_lsn'::pg_lsn - :'start_lsn'::pg_lsn); 
  pg_size_pretty ---------------- 3114 MB (1 row) 

рддреЛ, рд╣рдореЗрдВ рд▓рдЧрднрдЧ 3 рдЬреАрдмреА рдорд┐рд▓рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╣рдо GIN рдЗрдВрдбреЗрдХреНрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдкреНрд░рдпреЛрдЧ рджреЛрд╣рд░рд╛рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд▓рдЧрднрдЧ 700 рдПрдордмреА рдХрд╛ рд╣реЛрдЧрд╛ред

рдЗрд╕рд▓рд┐рдП, рдПрдХ рдЕрд▓рдЧ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реЛрдирд╛ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ, рдЬреЛ рдХрд┐ рдиреНрдпреВрдирддрдо рд╕рдВрдЦреНрдпрд╛ рдбрд╛рд▓реЗрдВ рдФрд░ рдСрдкрд░реЗрд╢рди рдХреЛ рд╣рдЯрд╛ рджреЗрдВ рдЬреЛ рдкреГрд╖реНрда рдХреЗ рдПрдХ рд░рд╛рдЬреНрдп рдХреЛ рджреВрд╕рд░реЗ рдореЗрдВ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред "рдбрд┐рдл" рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдПрдХ рд╕рдорд╛рди рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИред рдУрд▓реЗрдЧ рдЗрд╡рд╛рдиреЛрд╡ рдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рд╣реИ, рдФрд░ рдЙрдирдХреЗ рдкреИрдЪ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛ рд░рд╣реА рд╣реИред рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдпрд╣ рдкреИрдЪ рд╣рдореЗрдВ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдордВрджреА рдХреА рдХреАрдордд рдкрд░, рд▓реЙрдЧ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рез.рел рдПрдордмреА рддрдХ рдХрдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддрд╛ рд╣реИред

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдкреИрдЪ рдЕрдЯрдХ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХреЛрдИ рдЧрддрд┐рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИред

рдЧреБрдг


рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, RUM рдкрд╣реБрдВрдЪ рд╡рд┐рдзрд┐ рдХреЗ рдЧреБрдгреЛрдВ рдХреЛ рджреЗрдЦреЗрдВ, GIN рд╕реЗ рдЕрдВрддрд░реЛрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрддреЗ рд╣реБрдП (рдкреНрд░рд╢реНрди рдкрд╣рд▓реЗ рд╣реА рдкреНрд░рджрд╛рди рдХрд┐рдП рдЬрд╛ рдЪреБрдХреЗ рд╣реИрдВ )ред

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд╣реБрдБрдЪ рд╡рд┐рдзрд┐ рдХреЗ рдЧреБрдг рд╣реИрдВ:

  amname | name | pg_indexam_has_property --------+---------------+------------------------- rum | can_order | f rum | can_unique | f rum | can_multi_col | t rum | can_exclude | t -- f for gin 

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реВрдЪрдХрд╛рдВрдХ-рдкрд░рдд рдЧреБрдг рдЙрдкрд▓рдмреНрдз рд╣реИрдВ:

  name | pg_index_has_property ---------------+----------------------- clusterable | f index_scan | t -- f for gin bitmap_scan | t backward_scan | f 

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐, GIN рдХреЗ рд╡рд┐рдкрд░реАрдд, RUM рд╕реВрдЪрдХрд╛рдВрдХ рд╕реНрдХреИрди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ - рдЕрдиреНрдпрдерд╛, "рд╕реАрдорд╛" рдЦрдВрдб рдХреЗ рд╕рд╛рде рдкреНрд░рд╢реНрдиреЛрдВ рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдХреА рдЖрд╡рд╢реНрдпрдХ рд╕рдВрдЦреНрдпрд╛ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рддрджрдиреБрд╕рд╛рд░ "gin_fuzzy_search_limit" рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рдордХрдХреНрд╖ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЗрдВрдбреЗрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд╣рд┐рд╖реНрдХрд░рдг рдмрд╛рдзрд╛рдУрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реНрддрдВрдн-рдкрд░рдд рдЧреБрдг рд╣реИрдВ:

  name | pg_index_column_has_property --------------------+------------------------------ asc | f desc | f nulls_first | f nulls_last | f orderable | f distance_orderable | t -- f for gin returnable | f search_array | f search_nulls | f 

рдпрд╣рд╛рдВ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ RUM рдСрд░реНрдбрд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рд╕рднреА рдСрдкрд░реЗрдЯрд░ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдирд╣реАрдВ рд╣реИ: рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ "tsquery_ops" рдХреЗ рд▓рд┐рдП рдЧрд▓рдд рд╣реИред

рдкрд░ рдкрдврд╝реЗрдВ ред

Source: https://habr.com/ru/post/hi452116/


All Articles