63.4. ÐндекÑÑ GIN #
63.4.1. Ðведение #
GIN ÑаÑÑиÑÑовÑваеÑÑÑ ÐºÐ°Ðº «Generalized Inverted Index» (ÐбобÑÑннÑй инвеÑÑиÑованнÑй индекÑ). GIN пÑедназнаÑаеÑÑÑ Ð´Ð»Ñ ÑлÑÑаев, когда индекÑиÑÑемÑе знаÑÐµÐ½Ð¸Ñ ÑвлÑÑÑÑÑ ÑоÑÑавнÑми, а запÑоÑÑ, на обÑабоÑÐºÑ ÐºÐ¾ÑоÑÑÑ ÑаÑÑÑиÑан индекÑ, иÑÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÑлеменÑов в ÑÑÐ¸Ñ ÑоÑÑавнÑÑ Ð¾Ð±ÑекÑÐ°Ñ . ÐапÑимеÑ, Ñакими обÑекÑами могÑÑ Ð±ÑÑÑ Ð´Ð¾ÐºÑменÑÑ, а запÑоÑÑ Ð¼Ð¾Ð³ÑÑ Ð²ÑполнÑÑÑ Ð¿Ð¾Ð¸Ñк докÑменÑов, ÑодеÑжаÑÐ¸Ñ Ð¾Ð¿ÑеделÑннÑе Ñлова.
ÐдеÑÑ Ð¼Ñ Ð¸ÑполÑзÑем ÑеÑмин обÑекÑ, говоÑÑ Ð¾ ÑоÑÑавном знаÑении, коÑоÑое индекÑиÑÑеÑÑÑ, и ÑеÑмин клÑÑ, говоÑÑ Ð¾ вклÑÑÑнном в него ÑлеменÑе. GIN вÑегда Ñ ÑÐ°Ð½Ð¸Ñ Ð¸ иÑÐµÑ ÐºÐ»ÑÑи, а не обÑекÑÑ ÐºÐ°Ðº ÑаковÑе.
ÐÐ½Ð´ÐµÐºÑ GIN ÑÐ¾Ñ ÑанÑÐµÑ Ð½Ð°Ð±Ð¾Ñ Ð¿Ð°Ñ (клÑÑ, ÑпиÑок иденÑиÑикаÑоÑов), где ÑпиÑок иденÑиÑикаÑоÑов ÑодеÑÐ¶Ð¸Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑÑ ÑÑÑок, в коÑоÑÑÑ Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ ÐºÐ»ÑÑ. Ðдин и ÑÐ¾Ñ Ð¶Ðµ иденÑиÑикаÑÐ¾Ñ ÑÑÑоки Ð¼Ð¾Ð¶ÐµÑ ÑигÑÑиÑоваÑÑ Ð² неÑколÑÐºÐ¸Ñ ÑпиÑÐºÐ°Ñ , Ñак как обÑÐµÐºÑ Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ Ð±Ð¾Ð»ÑÑе одного клÑÑа. ÐнаÑение каждого клÑÑа Ñ ÑаниÑÑÑ ÑолÑко один Ñаз, Ñак ÑÑо Ð¸Ð½Ð´ÐµÐºÑ GIN оÑÐµÐ½Ñ ÐºÐ¾Ð¼Ð¿Ð°ÐºÑен в ÑлÑÑаÑÑ , когда один клÑÑ Ð²ÑÑÑеÑаеÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ Ñаз.
GIN ÑвлÑеÑÑÑ Ð¾Ð±Ð¾Ð±ÑÑннÑм в Ñом ÑмÑÑле, ÑÑо код меÑода доÑÑÑпа GIN не должен знаÑÑ Ð¾ конкÑеÑнÑÑ Ð¾Ð¿ÐµÑаÑиÑÑ , коÑоÑÑе он ÑÑкоÑÑеÑ. ÐмеÑÑо ÑÑого задаÑÑÑÑ ÑпеÑиалÑнÑе ÑÑÑаÑегии Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑеÑнÑÑ Ñипов даннÑÑ . СÑÑаÑÐµÐ³Ð¸Ñ Ð¾Ð¿ÑеделÑеÑ, как извлекаÑÑÑÑ ÐºÐ»ÑÑи из индекÑиÑÑемÑÑ Ð¾Ð±ÑекÑов и ÑÑловий запÑоÑов, и как ÑÑÑановиÑÑ, дейÑÑвиÑелÑно ли ÑдовлеÑвоÑÑÐµÑ Ð·Ð°Ð¿ÑоÑÑ ÑÑÑока, ÑодеÑжаÑÐ°Ñ Ð½ÐµÐºÐ¾ÑоÑÑе знаÑÐµÐ½Ð¸Ñ ÐºÐ»ÑÑей.
ÐлÑÑевÑм пÑеимÑÑеÑÑвом GIN ÑвлÑеÑÑÑ Ñо, ÑÑо он позволÑÐµÑ ÑазÑабаÑÑваÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе ÑÐ¸Ð¿Ñ Ð´Ð°Ð½Ð½ÑÑ Ñ ÑооÑвеÑÑÑвÑÑÑими меÑодами доÑÑÑпа ÑкÑпеÑÑам в пÑедмеÑной облаÑÑи Ñипа даннÑÑ , а не ÑпеÑиалиÑÑам по СУÐÐ. Ð ÑÑом аÑпекÑе он Ð¿Ð¾Ñ Ð¾Ð¶ на GiST.
СопÑовождением ÑеализаÑии GIN в Postgres Pro в оÑновном занимаÑÑÑÑ Ð¤ÑÐ´Ð¾Ñ Ð¡Ð¸Ð³Ð°ÐµÐ² и Ðлег ÐаÑÑÑнов. ÐополниÑелÑнÑе ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ GIN можно полÑÑиÑÑ Ð½Ð° Ð¸Ñ ÑайÑе.
63.4.2. ÐÑÑÑоеннÑе клаÑÑÑ Ð¾Ð¿ÐµÑаÑоÑов #
РбазовÑй диÑÑÑибÑÑив Postgres Pro вклÑÑÐµÐ½Ñ ÐºÐ»Ð°ÑÑÑ Ð¾Ð¿ÐµÑаÑоÑов GIN, пеÑеÑиÑленнÑе в ТаблиÑе 63.3. (ÐекоÑоÑÑе дополниÑелÑнÑе модÑли, опиÑаннÑе в ÐÑиложении F, добавлÑÑÑ Ð´ÑÑгие клаÑÑÑ Ð¾Ð¿ÐµÑаÑоÑов GIN.)
ТаблиÑа 63.3. ÐÑÑÑоеннÑе клаÑÑÑ Ð¾Ð¿ÐµÑаÑоÑов GIN
| ÐÐ¼Ñ | ÐндекÑиÑÑемÑе опеÑаÑоÑÑ |
|---|---|
array_ops | && (anyarray,anyarray) |
@> (anyarray,anyarray) | |
<@ (anyarray,anyarray) | |
= (anyarray,anyarray) | |
jsonb_ops | @> (jsonb,jsonb) |
@? (jsonb,jsonpath) | |
@@ (jsonb,jsonpath) | |
? (jsonb,text) | |
?| (jsonb,text[]) | |
?& (jsonb,text[]) | |
jsonb_path_ops | @> (jsonb,jsonb) |
@? (jsonb,jsonpath) | |
@@ (jsonb,jsonpath) | |
tsvector_ops | @@ (tsvector,tsquery) |
Ðз двÑÑ
клаÑÑов опеÑаÑоÑов Ð´Ð»Ñ Ñипа jsonb клаÑÑом по ÑмолÑÐ°Ð½Ð¸Ñ ÑвлÑеÑÑÑ jsonb_ops. ÐлаÑÑ jsonb_path_ops поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¼ÐµÐ½ÑÑе опеÑаÑоÑов, но обеÑпеÑÐ¸Ð²Ð°ÐµÑ Ð´Ð»Ñ Ð½Ð¸Ñ
болÑÑÑÑ Ð¿ÑоизводиÑелÑноÑÑÑ. Ðа подÑобноÑÑÑми обÑаÑиÑеÑÑ Ðº ÐодÑазделÑ 8.14.4.
63.4.3. РаÑÑиÑÑемоÑÑÑ #
ÐнÑеÑÑÐµÐ¹Ñ GIN Ñ Ð°ÑакÑеÑизÑеÑÑÑ Ð²ÑÑоким ÑÑовнем абÑÑÑакÑии и Ñаким обÑазом ÑÑебÑÐµÑ Ð¾Ñ ÑазÑабоÑÑика меÑода доÑÑÑпа ÑеализоваÑÑ ÑолÑко ÑмÑÑловое наполнение обÑабаÑÑваемого Ñипа даннÑÑ . УÑÐ¾Ð²ÐµÐ½Ñ GIN беÑÑÑ Ð½Ð° ÑÐµÐ±Ñ Ð·Ð°Ð±Ð¾ÑÑ Ð¾ паÑаллелÑном доÑÑÑпе, поддеÑжке жÑÑнала и поиÑке в ÑÑÑÑкÑÑÑе деÑева.
ÐÑÑ, ÑÑо нÑжно, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ ÑабоÑаÑÑий меÑод доÑÑÑпа GIN â ÑÑо ÑеализоваÑÑ Ð½ÐµÑколÑко полÑзоваÑелÑÑÐºÐ¸Ñ Ð¼ÐµÑодов, опÑеделÑÑÑÐ¸Ñ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ клÑÑей в деÑеве и оÑноÑÐµÐ½Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñ ÐºÐ»ÑÑами, индекÑиÑÑемÑми обÑекÑами и поддеÑживаемÑми запÑоÑами. Словом, GIN ÑоÑеÑÐ°ÐµÑ ÑаÑÑиÑÑемоÑÑÑ Ñ ÑнивеÑÑалÑноÑÑÑÑ, повÑоÑнÑм иÑполÑзованием кода и аккÑÑаÑнÑм инÑеÑÑейÑом.
ÐлаÑÑ Ð¾Ð¿ÐµÑаÑоÑов должен пÑедоÑÑавиÑÑ GIN ÑледÑÑÑие два меÑода:
Datum *extractValue(Datum itemValue, int32 *nkeys, bool **nullFlags)ÐозвÑаÑÐ°ÐµÑ Ð¼Ð°ÑÑив клÑÑей (вÑделеннÑй ÑеÑез palloc) Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑиÑÑемого обÑекÑа. ЧиÑло возвÑаÑаемÑÑ ÐºÐ»ÑÑей должно запиÑÑваÑÑÑÑ Ð²
*nkeys. ÐÑли какой-либо из клÑÑей Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ NULL, нÑжно Ñак же вÑделиÑÑ ÑеÑез palloc маÑÑив из*nkeysполейbool, запиÑаÑÑ ÐµÐ³Ð¾ адÑÐµÑ Ð²*nullFlagsи ÑÑÑановиÑÑ ÑÑи Ñлаги NULL как ÑÑебÑеÑÑÑ. Ð*nullFlagsможно оÑÑавиÑÑ Ð·Ð½Ð°ÑениеNULL(ÑÑо наÑалÑное знаÑение), еÑли вÑе клÑÑи оÑлиÑÐ½Ñ Ð¾Ñ NULL. ÐÑа ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑиÑÑNULL, еÑли обÑÐµÐºÑ Ð½Ðµ ÑодеÑÐ¶Ð¸Ñ ÐºÐ»ÑÑей.Datum *extractQuery(Datum query, int32 *nkeys, StrategyNumber n, bool **pmatch, Pointer **extra_data, bool **nullFlags, int32 *searchMode)ÐозвÑаÑÐ°ÐµÑ Ð¼Ð°ÑÑив клÑÑей (вÑделеннÑй ÑеÑез palloc) Ð´Ð»Ñ Ð·Ð°Ð¿ÑаÑиваемого знаÑениÑ; Ñо еÑÑÑ, в
queryпоÑÑÑÐ¿Ð°ÐµÑ Ð·Ð½Ð°Ñение, Ð½Ð°Ñ Ð¾Ð´ÑÑееÑÑ Ð¿Ð¾ пÑавÑÑ ÑÑоÑÐ¾Ð½Ñ Ð¸Ð½Ð´ÐµÐºÑиÑÑемого опеÑаÑоÑа, по левÑÑ ÑÑоÑÐ¾Ð½Ñ ÐºÐ¾ÑоÑого Ñказан индекÑиÑÑемÑй ÑÑолбеÑ. ÐÑгÑменÑnзадаÑÑ Ð½Ð¾Ð¼ÐµÑ ÑÑÑаÑегии опеÑаÑоÑа в клаÑÑе опеÑаÑоÑов (Ñм. ÐодÑаздел 36.16.2). ЧаÑÑо ÑÑнкÑиÑextractQueryдолжна пÑоанализиÑоваÑÑn, ÑÑÐ¾Ð±Ñ Ð¾Ð¿ÑеделиÑÑ Ñип даннÑÑ Ð°ÑгÑменÑаqueryи вÑбÑаÑÑ Ð¼ÐµÑод Ð´Ð»Ñ Ð¸Ð·Ð²Ð»ÐµÑÐµÐ½Ð¸Ñ Ð·Ð½Ð°Ñений клÑÑей. ЧиÑло возвÑаÑаемÑÑ ÐºÐ»ÑÑей должно бÑÑÑ Ð·Ð°Ð¿Ð¸Ñано в*nkeys. ÐÑли какие-либо клÑÑи могÑÑ Ð±ÑÑÑ NULL, нÑжно Ñак же вÑделиÑÑ ÑеÑез palloc маÑÑив из*nkeysполейbool, ÑÐ¾Ñ ÑаниÑÑ ÐµÐ³Ð¾ адÑÐµÑ Ð²*nullFlags, и ÑÑÑановиÑÑ ÑÑи Ñлаги NULL как ÑÑебÑеÑÑÑ. Ð*nullFlagsможно оÑÑавиÑÑ Ð·Ð½Ð°ÑениеNULL(ÑÑо наÑалÑное знаÑение), еÑли вÑе клÑÑи оÑлиÑÐ½Ñ Ð¾Ñ NULL. ÐÑа ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑиÑÑNULL, еÑлиqueryне ÑодеÑÐ¶Ð¸Ñ ÐºÐ»ÑÑей.ÐÑÑ Ð¾Ð´Ð½Ð¾Ð¹ аÑгÑменÑ
searchModeпозволÑÐµÑ ÑÑнкÑииextractQueryвÑбÑаÑÑ Ñежим, в коÑоÑом должен вÑполнÑÑÑÑÑ Ð¿Ð¾Ð¸Ñк. ÐÑли*searchModeÐ¸Ð¼ÐµÐµÑ Ð·Ð½Ð°ÑениеGIN_SEARCH_MODE_DEFAULT(ÑÑо знаÑение ÑÑÑанавливаеÑÑÑ Ð¿ÐµÑед вÑзовом), Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑими кандидаÑами ÑÑиÑаÑÑÑÑ ÑолÑко Ñе обÑекÑÑ, коÑоÑÑе ÑооÑвеÑÑÑвÑÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ñм Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð¸Ð· возвÑаÑÑннÑÑ ÐºÐ»ÑÑей. ÐÑли в*searchModeÑÑÑановлено знаÑениеGIN_SEARCH_MODE_INCLUDE_EMPTY, Ñо в дополнение к обÑекÑам Ñ Ð¼Ð¸Ð½Ð¸Ð¼Ñм одним Ñовпадением клÑÑа, Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑими кандидаÑами бÑдÑÑ ÑÑиÑаÑÑÑÑ Ð¸ обÑекÑÑ, вообÑе не ÑодеÑжаÑие клÑÑей. (ÐÑÐ¾Ñ Ñежим полезен Ð´Ð»Ñ ÑеализаÑии, напÑимеÑ, опеÑаÑоÑов A-ÑвлÑеÑÑÑ-подмножеÑÑвом-B.) ÐÑли в*searchModeÑÑÑановлено знаÑениеGIN_SEARCH_MODE_ALL, Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑими кандидаÑами ÑÑиÑаÑÑÑÑ Ð²Ñе оÑлиÑнÑе Ð¾Ñ NULL обÑекÑÑ Ð² индекÑе, незавиÑимо Ð¾Ñ Ñого, вÑÑÑеÑаÑÑÑÑ Ð»Ð¸ в Ð½Ð¸Ñ Ð²Ð¾Ð·Ð²ÑаÑаемÑе клÑÑи. (ÐÑÐ¾Ñ Ñежим намного медленнее двÑÑ Ð´ÑÑÐ³Ð¸Ñ , Ñак как он по ÑÑÑи ÑÑебÑÐµÑ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð²Ñего индекÑа, но он Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼ Ð´Ð»Ñ ÐºÐ¾ÑÑекÑной обÑабоÑки кÑÐ°Ð¹Ð½Ð¸Ñ ÑлÑÑаев. ÐпеÑаÑоÑ, коÑоÑÑй вÑбиÑÐ°ÐµÑ ÑÑÐ¾Ñ Ñежим в болÑÑинÑÑве ÑиÑÑаÑий, ÑкоÑее вÑего не Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð¸Ñ Ð´Ð»Ñ ÑеализаÑии в клаÑÑе опеÑаÑоÑов GIN.) Ð¡Ð¸Ð¼Ð²Ð¾Ð»Ñ Ð´Ð»Ñ ÑÑÐ¸Ñ Ð·Ð½Ð°Ñений Ñежима опÑÐµÐ´ÐµÐ»ÐµÐ½Ñ Ð²access/gin.h.ÐÑÑ Ð¾Ð´Ð½Ð¾Ð¹ аÑгÑменÑ
pmatchиÑполÑзÑеÑÑÑ, когда поддеÑживаеÑÑÑ ÑаÑÑиÑное ÑооÑвеÑÑÑвие. ЧÑÐ¾Ð±Ñ Ð¸ÑполÑзоваÑÑ ÐµÐ³Ð¾,extractQueryдолжна вÑделиÑÑ Ð¼Ð°ÑÑив из*nkeysлогиÑеÑÐºÐ¸Ñ ÑлеменÑов и ÑÐ¾Ñ ÑаниÑÑ ÐµÐ³Ð¾ адÑÐµÑ Ð²*pmatch. ÐÐ»ÐµÐ¼ÐµÐ½Ñ ÑÑого маÑÑива должен ÑодеÑжаÑÑ true, еÑли ÑооÑвеÑÑÑвÑÑÑий клÑÑ ÑÑебÑÐµÑ ÑаÑÑиÑного ÑооÑвеÑÑÑвиÑ, и false в пÑоÑивном ÑлÑÑае. ÐÑли пеÑеменнаÑ*pmatchÑодеÑжиÑNULL, GIN полагаеÑ, ÑÑо ÑаÑÑиÑное ÑооÑвеÑÑÑвие не ÑÑебÑеÑÑÑ. Ð ÑÑÑ Ð¿ÐµÑеменнÑÑ Ð·Ð°Ð¿Ð¸ÑÑваеÑÑÑNULLпеÑед вÑзовом, Ñак ÑÑо ÑÑÐ¾Ñ Ð°ÑгÑÐ¼ÐµÐ½Ñ Ð¼Ð¾Ð¶Ð½Ð¾ пÑоÑÑо игноÑиÑоваÑÑ Ð² клаÑÑÐ°Ñ Ð¾Ð¿ÐµÑаÑоÑов, не поддеÑживаÑÑÐ¸Ñ ÑаÑÑиÑное ÑооÑвеÑÑÑвие.ÐÑÑ Ð¾Ð´Ð½Ð¾Ð¹ аÑгÑменÑ
extra_dataпозволÑÐµÑ ÑÑнкÑииextractQueryпеÑедаÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе даннÑе меÑодамconsistentиcomparePartial. ЧÑÐ¾Ð±Ñ Ð¸ÑполÑзоваÑÑ ÐµÐ³Ð¾,extractQueryдолжна вÑделиÑÑ Ð¼Ð°ÑÑив из*nkeysÑказаÑелей и ÑÐ¾Ñ ÑаниÑÑ ÐµÐ³Ð¾ адÑÐµÑ Ð²*extra_data, а заÑем ÑÐ¾Ñ ÑаниÑÑ Ð²ÑÑ, ÑÑо ей ÑÑебÑеÑÑÑ, в оÑделÑнÑÑ ÑказаÑелÑÑ . Ð ÑÑÑ Ð¿ÐµÑеменнÑÑ Ð·Ð°Ð¿Ð¸ÑÑваеÑÑÑNULLпеÑед вÑзовом, поÑÑÐ¾Ð¼Ñ Ð´Ð°Ð½Ð½Ñй аÑгÑÐ¼ÐµÐ½Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоÑÑо игноÑиÑоваÑÑÑÑ ÐºÐ»Ð°ÑÑами опеÑаÑоÑов, коÑоÑÑм не нÑÐ¶Ð½Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе даннÑе. ÐÑли маÑÑив*extra_dataзадан, он Ñеликом пеÑедаÑÑÑÑ Ð² меÑодconsistent, а вcomparePartialпеÑедаÑÑÑÑ ÑооÑвеÑÑÑвÑÑÑий его ÑлеменÑ.
ÐлаÑÑ Ð¾Ð¿ÐµÑаÑоÑов должен Ñакже пÑедоÑÑавиÑÑ ÑÑнкÑÐ¸Ñ Ð´Ð»Ñ Ð¿ÑовеÑки, ÑооÑвеÑÑÑвÑÐµÑ Ð»Ð¸ индекÑиÑованнÑй обÑÐµÐºÑ Ð·Ð°Ð¿ÑоÑÑ. ÐоддеÑживаÑÑÑÑ Ð´Ð²Ðµ ÐµÑ Ð²Ð°ÑиаÑии: бÑлева consistent и ÑÑоиÑÐ½Ð°Ñ triConsistent. ФÑнкÑÐ¸Ñ triConsistent покÑÑÐ²Ð°ÐµÑ ÑÑнкÑионалÑноÑÑÑ Ð¾Ð±Ð¾Ð¸Ñ
, Ñак ÑÑо доÑÑаÑоÑно ÑеализоваÑÑ ÑолÑко еÑ. Ðднако еÑли вÑÑиÑление бÑлевой ваÑиаÑии оказÑваеÑÑÑ Ð·Ð½Ð°ÑиÑелÑно деÑевле, Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ ÑмÑÑл ÑеализоваÑÑ Ð¸Ñ
обе. ÐÑли пÑедÑÑавлена ÑолÑко бÑлева ваÑиаÑиÑ, некоÑоÑÑе опÑимизаÑии, поÑÑÑоеннÑе на оÑбÑаковÑвании обÑекÑов до вÑбоÑки вÑеÑ
клÑÑей, оÑклÑÑаÑÑÑÑ.
bool consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], bool *recheck, Datum queryKeys[], bool nullFlags[])ÐозвÑаÑÐ°ÐµÑ true, еÑли индекÑиÑованнÑй обÑÐµÐºÑ ÑдовлеÑвоÑÑÐµÑ Ð¾Ð¿ÐµÑаÑоÑÑ Ð·Ð°Ð¿ÑоÑа Ñ Ð½Ð¾Ð¼ÐµÑом ÑÑÑаÑегии
n(или поÑенÑиалÑно ÑдовлеÑвоÑÑеÑ, когда возвÑаÑаеÑÑÑ Ñказание пеÑепÑовеÑки). ÐÑа ÑÑнкÑÐ¸Ñ Ð½Ðµ Ð¸Ð¼ÐµÐµÑ Ð¿ÑÑмого доÑÑÑпа к знаÑÐµÐ½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑиÑованного обÑекÑа, Ñак как GIN не Ñ ÑÐ°Ð½Ð¸Ñ Ñами обÑекÑÑ. ÐмеÑÑо ÑÑого, она Ð·Ð½Ð°ÐµÑ Ð¾ знаÑениÑÑ ÐºÐ»ÑÑей, извлеÑÑннÑÑ Ð¸Ð· запÑоÑа и вÑÑÑеÑаÑÑÐ¸Ñ ÑÑ Ð² данном индекÑиÑованном обÑекÑе. ÐаÑÑивcheckÐ¸Ð¼ÐµÐµÑ Ð´Ð»Ð¸Ð½Ñnkeys, ÑÑо ÑавнÑеÑÑÑ ÑиÑÐ»Ñ ÐºÐ»ÑÑей, Ñанее возвÑаÑÑннÑÑ ÑÑнкÑиейextractQueryÐ´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ знаÑениÑquery. ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð°ÑÑиваcheckÑавнÑеÑÑÑ true, еÑли индекÑиÑованнÑй обÑÐµÐºÑ ÑодеÑÐ¶Ð¸Ñ ÑооÑвеÑÑÑвÑÑÑий клÑÑ Ð·Ð°Ð¿ÑоÑа; Ñо еÑÑÑ, еÑли (check[i] == true), Ñо i-й клÑÑ Ð² маÑÑиве ÑезÑлÑÑаÑаextractQueryпÑиÑÑÑÑÑвÑÐµÑ Ð² индекÑиÑованном обÑекÑе. ÐÑÑ Ð¾Ð´Ð½Ð¾Ðµ знаÑениеqueryпеÑедаÑÑÑÑ Ð½Ð° ÑлÑÑай, еÑли оно поÑÑебÑеÑÑÑ Ð¼ÐµÑодÑconsistent; Ñ Ñой же ÑелÑÑ ÐµÐ¼Ñ Ð¿ÐµÑедаÑÑÑÑ Ð¼Ð°ÑÑивÑqueryKeys[]иnullFlags[], Ñанее возвÑаÑÑннÑе ÑÑнкÑиейextractQuery. РаÑгÑменÑеextra_dataпеÑедаÑÑÑÑ Ð¼Ð°ÑÑив дополниÑелÑнÑÑ Ð´Ð°Ð½Ð½ÑÑ , возвÑаÑÑннÑй ÑÑнкÑиейextractQuery, илиNULL, еÑли дополниÑелÑнÑÑ Ð´Ð°Ð½Ð½ÑÑ Ð½ÐµÑ.Ðогда
extractQueryвозвÑаÑÐ°ÐµÑ ÐºÐ»ÑÑ NULL вqueryKeys[], ÑооÑвеÑÑÑвÑÑÑий ÑлеменÑcheck[]ÑодеÑÐ¶Ð¸Ñ true, еÑли индекÑиÑованнÑй обÑÐµÐºÑ ÑодеÑÐ¶Ð¸Ñ ÐºÐ»ÑÑ NULL; Ñо еÑÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ ÑÑиÑаÑÑ, ÑÑо ÑлеменÑÑcheck[]оÑÑажаÑÑ ÑÑловиеIS NOT DISTINCT FROM. ФÑнкÑиÑconsistentÐ¼Ð¾Ð¶ÐµÑ Ð¿ÑовеÑиÑÑ ÑооÑвеÑÑÑвÑÑÑий ÑлеменÑnullFlags[], еÑли ей нÑжно ÑазлиÑаÑÑ ÑооÑвеÑÑÑвие Ñ Ð¾Ð±ÑÑнÑм знаÑением и ÑооÑвеÑÑÑвие Ñ NULL.Ð ÑлÑÑае ÑÑÐ¿ÐµÑ Ð° в
*recheckнÑжно запиÑаÑÑ true, еÑли коÑÑеж даннÑÑ Ð½Ñжно пеÑепÑовеÑиÑÑ Ñ Ð¾Ð¿ÐµÑаÑоÑом запÑоÑа, либо false, еÑли пÑовеÑка по индекÑÑ Ð±Ñла ÑоÑной. То еÑÑÑ ÑезÑлÑÑÐ°Ñ false гаÑанÑиÑÑеÑ, ÑÑо коÑÑеж даннÑÑ Ð½Ðµ ÑооÑвеÑÑÑвÑÐµÑ Ð·Ð°Ð¿ÑоÑÑ; ÑезÑлÑÑÐ°Ñ true Ñо знаÑением*recheck, ÑавнÑм false, гаÑанÑиÑÑеÑ, ÑÑо коÑÑеж даннÑÑ ÑооÑвеÑÑÑвÑÐµÑ Ð·Ð°Ð¿ÑоÑÑ; а ÑезÑлÑÑÐ°Ñ true Ñо знаÑением*recheck, ÑавнÑм true, ознаÑаеÑ, ÑÑо коÑÑеж даннÑÑ Ð¼Ð¾Ð¶ÐµÑ ÑооÑвеÑÑÑвоваÑÑ Ð·Ð°Ð¿ÑоÑÑ, поÑÑÐ¾Ð¼Ñ ÐµÐ³Ð¾ нÑжно вÑбÑаÑÑ Ð¸ пеÑепÑовеÑиÑÑ, пÑименив опеÑаÑÐ¾Ñ Ð·Ð°Ð¿ÑоÑа непоÑÑедÑÑвенно к иÑÑ Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð¸Ð½Ð´ÐµÐºÑиÑÐ¾Ð²Ð°Ð½Ð½Ð¾Ð¼Ñ ÑлеменÑÑ.GinTernaryValue triConsistent(GinTernaryValue check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], Datum queryKeys[], bool nullFlags[])ФÑнкÑиÑ
triConsistentподобнаconsistent, но вмеÑÑо бÑлевÑÑ Ð·Ð½Ð°Ñений в векÑоÑеcheckей пеÑедаÑÑÑÑ ÑÑи ваÑианÑа ÑÑавнений Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ клÑÑа:GIN_TRUE,GIN_FALSEиGIN_MAYBE.GIN_FALSEиGIN_TRUEимеÑÑ Ð¾Ð±ÑÑное логиÑеÑкое знаÑение, Ñогда какGIN_MAYBEознаÑаеÑ, ÑÑо пÑиÑÑÑÑÑвие клÑÑа неизвеÑÑно. Ðогда пÑиÑÑÑÑÑвÑÑÑ Ð·Ð½Ð°ÑениÑGIN_MAYBE, ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° возвÑаÑаÑÑGIN_TRUE, ÑолÑко еÑли обÑÐµÐºÑ ÑдовлеÑвоÑÑÐµÑ Ð·Ð°Ð¿ÑоÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимо Ð¾Ñ Ñого, ÑодеÑÐ¶Ð¸Ñ Ð»Ð¸ Ð¸Ð½Ð´ÐµÐºÑ ÑооÑвеÑÑÑвÑÑÑие клÑÑи запÑоÑа. ÐодобнÑм обÑазом, ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° возвÑаÑаÑÑGIN_FALSE, ÑолÑко еÑли обÑÐµÐºÑ Ð½Ðµ ÑдовлеÑвоÑÑÐµÑ Ð·Ð°Ð¿ÑоÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимо Ð¾Ñ Ñого, ÑодеÑÐ¶Ð¸Ñ Ð»Ð¸ он клÑÑиGIN_MAYBE. ÐÑли ÑезÑлÑÑÐ°Ñ Ð·Ð°Ð²Ð¸ÑÐ¸Ñ Ð¾Ñ ÑлеменÑовGIN_MAYBE, Ñо еÑÑÑ ÑооÑвеÑÑÑвие нелÑÐ·Ñ ÑÑвеÑждаÑÑ Ð¸Ð»Ð¸ оÑÑиÑаÑÑ Ð² завиÑимоÑÑи Ð¾Ñ Ð¸Ð·Ð²ÐµÑÑнÑÑ ÐºÐ»ÑÑей запÑоÑа, ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° веÑнÑÑÑGIN_MAYBE.Ðогда в векÑоÑе
checkÐ½ÐµÑ ÑлеменÑовGIN_MAYBE, возвÑаÑаемое знаÑениеGIN_MAYBEÑавнознаÑно ÑÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ð¾Ð¼Ñ ÑлагÑrecheckв бÑлевой ÑÑнкÑииconsistent.
ÐÑоме Ñого, GIN нÑжно каким-Ñо обÑазом ÑоÑÑиÑоваÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÐºÐ»ÑÑа, Ñ ÑанÑÑиеÑÑ Ð² индекÑе. ÐлаÑÑ Ð¾Ð¿ÐµÑаÑоÑов Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделиÑÑ Ð¿Ð¾ÑÑдок ÑоÑÑиÑовки, Ñказав меÑод ÑÑавнениÑ:
int compare(Datum a, Datum b)СÑÐ°Ð²Ð½Ð¸Ð²Ð°ÐµÑ Ð´Ð²Ð° клÑÑа (не индекÑиÑованнÑе обÑекÑÑ!) и возвÑаÑÐ°ÐµÑ Ñелое менÑÑе нÑлÑ, Ð½Ð¾Ð»Ñ Ð¸Ð»Ð¸ Ñелое болÑÑе нÑлÑ, показÑваÑÑее, ÑÑо пеÑвÑй клÑÑ Ð¼ÐµÐ½ÑÑе, Ñавен или болÑÑе вÑоÑого. ÐлÑÑи NULL никогда не пеÑедаÑÑÑÑ ÑÑой ÑÑнкÑии.
ÐÑли же клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов не опÑеделÑÐµÑ Ð¼ÐµÑод compare, GIN попÑÑаеÑÑÑ Ð½Ð°Ð¹Ñи клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов B-деÑева по ÑмолÑÐ°Ð½Ð¸Ñ Ð´Ð»Ñ Ñипа даннÑÑ
клÑÑа индекÑа и воÑполÑзоваÑÑÑÑ ÐµÐ³Ð¾ ÑÑнкÑией ÑÑавнениÑ. ÐÑли клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов GIN пÑедназнаÑен ÑолÑко Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ Ñипа даннÑÑ
, ÑекомендÑеÑÑÑ Ð·Ð°Ð´Ð°Ð²Ð°ÑÑ ÑÑнкÑÐ¸Ñ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ð² ÑÑом клаÑÑе опеÑаÑоÑов, Ñак как поиÑк клаÑÑа опеÑаÑоÑов B-деÑева Ð·Ð°Ð½Ð¸Ð¼Ð°ÐµÑ Ð½ÐµÑколÑко Ñиклов. Ðднако Ð´Ð»Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑнÑÑ
клаÑÑов опеÑаÑоÑов GIN (напÑимеÑ, array_ops) задаÑÑ Ð¾Ð´Ð½Ñ ÑÑнкÑÐ¸Ñ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±ÑÑно не пÑедÑÑавлÑеÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñм.
ÐополниÑелÑно клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов Ð´Ð»Ñ GIN Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑедоÑÑавиÑÑ ÑледÑÑÑие меÑодÑ:
int comparePartial(Datum partial_key, Datum key, StrategyNumber n, Pointer extra_data)СÑÐ°Ð²Ð½Ð¸Ð²Ð°ÐµÑ ÐºÐ»ÑÑ Ð·Ð°Ð¿ÑоÑа Ñ ÑаÑÑиÑнÑм ÑооÑвеÑÑÑвием Ñ ÐºÐ»ÑÑом индекÑа. ÐозвÑаÑÐ°ÐµÑ Ñелое ÑиÑло, знак коÑоÑого оÑÑÐ°Ð¶Ð°ÐµÑ ÑезÑлÑÑÐ°Ñ ÑÑавнениÑ: оÑÑиÑаÑелÑное ÑиÑло ознаÑаеÑ, ÑÑо клÑÑ Ð¸Ð½Ð´ÐµÐºÑа не ÑооÑвеÑÑÑвÑÐµÑ Ð·Ð°Ð¿ÑоÑÑ, но нÑжно пÑодолжаÑÑ ÑканиÑование индекÑа; Ð½Ð¾Ð»Ñ Ð¾Ð·Ð½Ð°ÑаеÑ, ÑÑо клÑÑ Ð¸Ð½Ð´ÐµÐºÑа ÑооÑвеÑÑÑвÑÐµÑ Ð·Ð°Ð¿ÑоÑÑ; положиÑелÑное ÑиÑло ознаÑаеÑ, ÑÑо ÑканиÑование индекÑа нÑжно пÑекÑаÑиÑÑ, Ñак как дÑÑÐ³Ð¸Ñ ÑооÑвеÑÑÑвий не бÑдеÑ. ФÑнкÑии пеÑедаÑÑÑÑ Ð½Ð¾Ð¼ÐµÑ ÑÑÑаÑегии
nопеÑаÑоÑа, ÑÑоÑмиÑовавÑего запÑÐ¾Ñ ÑаÑÑиÑного ÑооÑвеÑÑÑвиÑ, на ÑлÑÑай, еÑли нÑжно знаÑÑ ÐµÐ³Ð¾ ÑмÑÑл, ÑÑÐ¾Ð±Ñ Ð¾Ð¿ÑеделиÑÑ, когда пÑекÑаÑаÑÑ ÑканиÑование. ÐÑоме Ñого, ей пеÑедаÑÑÑÑextra_dataâ ÑооÑвеÑÑÑвÑÑÑий ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð°ÑÑива дополниÑелÑнÑÑ Ð´Ð°Ð½Ð½ÑÑ , ÑÑоÑмиÑованного ÑÑнкÑиейextractQuery, либоNULL, еÑли дополниÑелÑнÑÑ Ð´Ð°Ð½Ð½ÑÑ Ð½ÐµÑ. ÐнаÑÐµÐ½Ð¸Ñ NULL ÑÑой ÑÑнкÑии никогда не пеÑедаÑÑÑÑ.void options(local_relopts *relopts)ÐпÑеделÑÐµÑ Ð½Ð°Ð±Ð¾Ñ Ð²Ð¸Ð´Ð¸Ð¼ÑÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð¿Ð°ÑамеÑÑов, ÑпÑавлÑÑÑÐ¸Ñ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸ÐµÐ¼ клаÑÑа опеÑаÑоÑов.
ФÑнкÑии
optionsпеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑlocal_relopts, в коÑоÑÑÑ Ð½Ñжно внеÑÑи Ð½Ð°Ð±Ð¾Ñ Ð¿Ð°ÑамеÑÑов, оÑноÑÑÑÐ¸Ñ ÑÑ Ðº клаÑÑÑ Ð¾Ð¿ÐµÑаÑоÑов. ÐбÑаÑаÑÑÑÑ Ðº ÑÑим паÑамеÑÑам из дÑÑÐ³Ð¸Ñ Ð¾Ð¿Ð¾ÑнÑÑ ÑÑнкÑий можно Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¼Ð°ÐºÑоÑовPG_HAS_OPCLASS_OPTIONS()иPG_GET_OPCLASS_OPTIONS().Так как в GIN и извлеÑение клÑÑа из индекÑиÑÑемÑÑ Ð·Ð½Ð°Ñений, и его пÑедÑÑавление допÑÑкаÑÑ Ð³Ð¸Ð±ÐºÐ¾ÑÑÑ, могÑÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ð¿Ð°ÑамеÑÑÑ Ð´Ð»Ñ Ð½Ð°ÑÑÑойки ÑÑого индекÑа.
ÐÐ»Ñ Ð¿Ð¾Ð´Ð´ÐµÑжки пÑовеÑок на «ÑаÑÑиÑное ÑооÑвеÑÑÑвие» клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов должен пÑедоÑÑавиÑÑ Ð¼ÐµÑод comparePartial, а меÑод extractQuery должен ÑÑÑанавливаÑÑ Ð¿Ð°ÑамеÑÑ pmatch, когда вÑÑÑеÑаеÑÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° ÑаÑÑиÑное ÑооÑвеÑÑÑвие. Ðа подÑобноÑÑÑми обÑаÑиÑеÑÑ Ðº ÐодÑазделÑ 63.4.4.2.
ФакÑиÑеÑкие ÑÐ¸Ð¿Ñ Ð´Ð°Ð½Ð½ÑÑ
ÑазлиÑнÑÑ
знаÑений Datum, ÑпоминаемÑÑ
вÑÑе, завиÑÑÑ Ð¾Ñ ÐºÐ»Ð°ÑÑа опеÑаÑоÑов. ÐнаÑÐµÐ½Ð¸Ñ Ð¾Ð±ÑекÑов, пеÑедаваемÑе в extractValue, вÑегда имеÑÑ Ð²Ñ
одной Ñип клаÑÑа опеÑаÑоÑов, а вÑе знаÑÐµÐ½Ð¸Ñ ÐºÐ»ÑÑей Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ñипа, заданного паÑамеÑÑом STORAGE Ð´Ð»Ñ ÐºÐ»Ð°ÑÑа. Типом аÑгÑменÑа query, пеÑедаваемого ÑÑнкÑиÑм extractQuery, consistent и triConsistent, бÑÐ´ÐµÑ ÑÐ¾Ñ Ñип, ÑÑо Ñказан в каÑеÑÑве Ñипа пÑавого опеÑанда опеÑаÑоÑа-Ñлена клаÑÑа, опÑеделÑемого по номеÑÑ ÑÑÑаÑегии. ÐÑо не обÑзаÑелÑно должен бÑÑÑ Ð¸Ð½Ð´ÐµÐºÑиÑÑемÑй Ñип, доÑÑаÑоÑно лиÑÑ, ÑÑÐ¾Ð±Ñ Ð¸Ð· него можно бÑло извлеÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÐºÐ»ÑÑей, имеÑÑие нÑжнÑй Ñип. Ðднако ÑекомендÑеÑÑÑ, ÑÑÐ¾Ð±Ñ Ð² SQL-обÑÑвлениÑÑ
ÑÑиÑ
ÑÑÑÑ
опоÑнÑÑ
ÑÑнкÑий Ð´Ð»Ñ Ð°ÑгÑменÑа query назнаÑалÑÑ Ð¸Ð½Ð´ÐµÐºÑиÑÑемÑй Ñип клаÑÑа опеÑаÑоÑов, даже неÑмоÑÑÑ Ð½Ð° Ñо, ÑÑо ÑакÑиÑеÑкий Ñип Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð´ÑÑгим, в завиÑимоÑÑи Ð¾Ñ Ð¾Ð¿ÐµÑаÑоÑа.
63.4.4. РеализаÑÐ¸Ñ #
ÐнÑÑÑи Ð¸Ð½Ð´ÐµÐºÑ GIN ÑодеÑÐ¶Ð¸Ñ B-деÑево, поÑÑÑоенное по клÑÑам, где каждÑй клÑÑ ÑвлÑеÑÑÑ ÑлеменÑом одного или неÑколÑÐºÐ¸Ñ Ð¸Ð½Ð´ÐµÐºÑиÑованнÑÑ Ð¾Ð±ÑекÑов (напÑимеÑ, Ñленом маÑÑива) и где каждÑй коÑÑеж на ÑÑÑаниÑÐ°Ñ Ð»Ð¸ÑÑÑев ÑодеÑÐ¶Ð¸Ñ Ð»Ð¸Ð±Ð¾ ÑказаÑÐµÐ»Ñ Ð½Ð° B-деÑево ÑказаÑелей на даннÑе («деÑево иденÑиÑикаÑоÑов»), либо пÑоÑÑой ÑпиÑок ÑказаÑелей на даннÑе («ÑпиÑок иденÑиÑикаÑоÑов»), когда ÑÑÐ¾Ñ ÑпиÑок доÑÑаÑоÑно мал, ÑÑÐ¾Ð±Ñ ÑмеÑÑиÑÑÑÑ Ð² одном коÑÑеже индекÑа вмеÑÑе Ñо знаÑением клÑÑа. ÐÑи компоненÑÑ GIN-индекÑа Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ñ Ð½Ð° РиÑÑнке 63.1.
ÐаÑÐ¸Ð½Ð°Ñ Ñ PostgreSQL веÑÑии 9.1, в Ð¸Ð½Ð´ÐµÐºÑ Ð¼Ð¾Ð³ÑÑ Ð±ÑÑÑ Ð²ÐºÐ»ÑÑÐµÐ½Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÐºÐ»ÑÑей, ÑавнÑе NULL. ÐÑоме Ñого, в Ð¸Ð½Ð´ÐµÐºÑ Ð²ÑÑавлÑÑÑÑÑ NULL Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑиÑÑемÑÑ
обÑекÑов, ÑавнÑÑ
NULL или не ÑодеÑжаÑиÑ
клÑÑей, ÑоглаÑно ÑÑнкÑии extractValue. ÐÑо позволÑÐµÑ Ð½Ð°Ñ
одиÑÑ Ð¿Ñи поиÑке пÑÑÑÑе обÑекÑÑ, когда они Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð½Ð°Ð¹Ð´ÐµÐ½Ñ.
СоÑÑавнÑе индекÑÑ GIN ÑеализÑÑÑÑÑ Ð² виде одного B-деÑева по ÑоÑÑавнÑм знаÑениÑм (Ð½Ð¾Ð¼ÐµÑ ÑÑолбÑа, знаÑение клÑÑа). ÐнаÑÐµÐ½Ð¸Ñ ÐºÐ»ÑÑей Ð´Ð»Ñ ÑазлиÑнÑÑ ÑÑолбÑов могÑÑ Ð±ÑÑÑ ÑазнÑÑ Ñипов.
РиÑÑнок 63.1. ÐнÑÑÑеннее ÑÑÑÑойÑÑво GIN
63.4.4.1. ÐеÑодика бÑÑÑÑого Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ GIN #
ÐÑиÑода инвеÑÑиÑованного индекÑа Ñакова, ÑÑо обновление GIN обÑÑно Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð°Ñ Ð¾Ð¿ÐµÑаÑиÑ: пÑи добавлении или изменении одной ÑÑÑоки даннÑÑ
Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ Ð²ÑполниÑÑ Ð¼Ð½Ð¾Ð¶ÐµÑÑво добавлений запиÑей в Ð¸Ð½Ð´ÐµÐºÑ (Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ клÑÑа, извлеÑÑнного из индекÑиÑÑемого обÑекÑа). GIN Ð¼Ð¾Ð¶ÐµÑ Ð¾ÑложиÑÑ Ð±Ð¾Ð»ÑÑой обÑÑм ÑÑой ÑабоÑÑ, вÑÑавлÑÑ Ð½Ð¾Ð²Ñе коÑÑежи во вÑеменнÑй, неÑоÑÑиÑованнÑй ÑпиÑок запиÑей, ожидаÑÑиÑ
индекÑаÑии. Ðогда ÑаблиÑа оÑиÑаеÑÑÑ, авÑомаÑиÑеÑки анализиÑÑеÑÑÑ, вÑзÑваеÑÑÑ ÑÑнкÑÐ¸Ñ gin_clean_pending_list или ÑÐ°Ð·Ð¼ÐµÑ ÑÑого ÑпиÑка вÑеменного ÑпиÑка ÑÑановиÑÑÑ Ð±Ð¾Ð»ÑÑе Ñем gin_pending_list_limit, запиÑи пеÑеноÑÑÑÑÑ Ð² оÑновнÑÑ ÑÑÑÑкÑÑÑÑ Ð´Ð°Ð½Ð½ÑÑ
GIN Ñеми же меÑодами маÑÑового Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
, ÑÑо и пÑи наÑалÑном Ñоздании индекÑа. ÐÑо знаÑиÑелÑно ÑвелиÑÐ¸Ð²Ð°ÐµÑ ÑкоÑоÑÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа GIN, даже Ñ ÑÑÑÑом дополниÑелÑнÑÑ
издеÑжек пÑи оÑиÑÑке. Ð ÑÐ¾Ð¼Ñ Ð¶Ðµ ÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ ÑабоÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ вÑполниÑÑ Ð² Ñоновом пÑоÑеÑÑе, а не в пÑоÑеÑÑе, непоÑÑедÑÑвенно вÑполнÑÑÑем запÑоÑÑ.
ÐÑновной недоÑÑаÑок Ñакого Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð° ÑоÑÑÐ¾Ð¸Ñ Ð² Ñом, ÑÑо пÑи поиÑке Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ не ÑолÑко пÑовеÑиÑÑ Ð¾Ð±ÑÑнÑй индекÑ, но и пÑоÑканиÑоваÑÑ ÑпиÑок ожидаÑÑÐ¸Ñ Ð·Ð°Ð¿Ð¸Ñей, Ñак ÑÑо еÑли ÑÑÐ¾Ñ ÑпиÑок болÑÑой, поиÑк знаÑиÑелÑно замедлÑеÑÑÑ. ÐÑÑ Ð¾Ð´Ð¸Ð½ недоÑÑаÑок ÑоÑÑÐ¾Ð¸Ñ Ð² Ñом, ÑÑо Ñ Ð¾ÑÑ Ð² оÑновном Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿ÑоизводÑÑÑÑ Ð±ÑÑÑÑо, изменение, пÑи коÑоÑом ÑÑÐ¾Ñ ÑпиÑок оказÑваеÑÑÑ Â«ÑлиÑком болÑÑим», влеÑÑÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑÑ Ð½ÐµÐ¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾Ð¹ оÑиÑÑки и поÑÑÐ¾Ð¼Ñ Ð²ÑполнÑеÑÑÑ Ð³Ð¾Ñаздо долÑÑе оÑÑалÑнÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹. ÐинимизиÑоваÑÑ ÑÑи недоÑÑаÑки можно, пÑавилÑно оÑганизовав авÑооÑиÑÑкÑ.
ÐÑли вÑдеÑжанноÑÑÑ Ð²Ñемени опеÑаÑий важнее ÑкоÑоÑÑи обновлениÑ, пÑименение ÑпиÑка ожидаÑÑиÑ
запиÑей можно оÑклÑÑиÑÑ, вÑклÑÑив паÑамеÑÑ Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ fastupdate Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑа GIN. Ðа подÑобноÑÑÑми обÑаÑиÑеÑÑ Ðº CREATE INDEX.
63.4.4.2. ÐлгоÑиÑм ÑаÑÑиÑного ÑооÑвеÑÑÑÐ²Ð¸Ñ #
GIN Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð´Ð´ÐµÑживаÑÑ Ð¿ÑовеÑки «ÑаÑÑиÑного ÑооÑвеÑÑÑвиÑ», когда запÑÐ¾Ñ Ð²ÑÑвлÑÐµÑ Ð½Ðµ ÑоÑное ÑооÑвеÑÑÑвие Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð¸Ð»Ð¸ неÑколÑким клÑÑам, а возможнÑе ÑооÑвеÑÑÑвиÑ, попадаÑÑие в доÑÑаÑоÑно Ñзкий диапазон знаÑений клÑÑей (пÑи поÑÑдке ÑоÑÑиÑовки клÑÑей, опÑеделÑннÑм опоÑнÑм меÑодом compare). Ð ÑÑом ÑлÑÑае меÑод extractQuery возвÑаÑÐ°ÐµÑ Ð½Ðµ знаÑение клÑÑа, коÑоÑое должно ÑооÑвеÑÑÑвоваÑÑ ÑоÑно, а знаÑение, опÑеделÑÑÑее нижнÑÑ Ð³ÑаниÑÑ Ð¸Ñкомого диапазона, и ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ñлаг pmatch. ÐаÑем диапазон клÑÑей ÑканиÑÑеÑÑÑ Ð¼ÐµÑодом comparePartial. ÐеÑод comparePartial должен веÑнÑÑÑ Ð½Ð¾Ð»Ñ Ð¿Ñи ÑооÑвеÑÑÑвии клÑÑа индекÑа, оÑÑиÑаÑелÑное знаÑение, еÑли ÑооÑвеÑÑÑÐ²Ð¸Ñ Ð½ÐµÑ, но нÑжно пÑодолжаÑÑ Ð¿ÑовеÑÐºÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð°, и положиÑелÑное знаÑение, еÑли клÑÑ Ð¸Ð½Ð´ÐµÐºÑа оказалÑÑ Ð·Ð° иÑкомÑм диапазоном.
63.4.5. ÐÑиÑÐ¼Ñ Ð¸ ÑовеÑÑ Ð¿Ð¾ пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ GIN #
- Создание или добавление
Ðобавление обÑекÑов в Ð¸Ð½Ð´ÐµÐºÑ GIN Ð¼Ð¾Ð¶ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾, Ñак как Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ обÑекÑа ÑкоÑее вÑего поÑÑебÑеÑÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑ Ð¼Ð½Ð¾Ð¶ÐµÑÑво клÑÑей. ÐоÑÑÐ¾Ð¼Ñ Ð¿Ñи маÑÑовом добавлении даннÑÑ Ð² ÑаблиÑÑ ÑекомендÑеÑÑÑ ÑдалиÑÑ Ð¸Ð½Ð´ÐµÐºÑ GIN и пеÑеÑоздаÑÑ ÐµÐ³Ð¾ по оконÑании добавлениÑ.
Ðогда Ð´Ð»Ñ GIN вклÑÑÑн Ñежим
fastupdate(за подÑобноÑÑÑми обÑаÑиÑеÑÑ Ðº ÐодÑазделÑ 63.4.4.1), издеÑжки менÑÑе, Ñем когда он оÑклÑÑÑн. Ðо пÑи оÑÐµÐ½Ñ Ð±Ð¾Ð»ÑÑом обÑÑме изменений вÑÑ Ð¶Ðµ лÑÑÑе ÑдалиÑÑ Ð¸ заново ÑоздаÑÑ Ð¸Ð½Ð´ÐµÐºÑ.- maintenance_work_mem
ÐÑÐµÐ¼Ñ Ð¿Ð¾ÑÑÑÐ¾ÐµÐ½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа GIN оÑÐµÐ½Ñ ÑилÑно завиÑÐ¸Ñ Ð¾Ñ Ð¿Ð°ÑамеÑÑа
maintenance_work_mem; не ÑÑÐ¾Ð¸Ñ ÑкономиÑÑ Ð½Ð° ÑабоÑей памÑÑи пÑи Ñоздании индекÑа.- gin_pending_list_limit
РпÑоÑеÑÑе поÑледоваÑелÑнÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ð¹ в ÑÑÑеÑÑвÑÑÑий Ð¸Ð½Ð´ÐµÐºÑ GIN Ñ Ð²ÐºÐ»ÑÑÑннÑм Ñежимом
fastupdate, ÑиÑÑема бÑÐ´ÐµÑ Ð¾ÑиÑаÑÑ ÑпиÑок ожидаÑÑÐ¸Ñ Ð¸Ð½Ð´ÐµÐºÑаÑии запиÑей, когда его ÑÐ°Ð·Ð¼ÐµÑ Ð±ÑÐ´ÐµÑ Ð¿ÑевÑÑаÑÑgin_pending_list_limit. Ðо избежание знаÑиÑелÑнÑÑ ÐºÐ¾Ð»ÐµÐ±Ð°Ð½Ð¸Ð¹ конеÑного вÑемени оÑвеÑа Ð¸Ð¼ÐµÐµÑ ÑмÑÑл пÑоводиÑÑ Ð¾ÑиÑÑÐºÑ ÑÑого ÑпиÑка в Ñоновом Ñежиме (Ñо еÑÑÑ, пÑименÑÑ Ð°Ð²ÑооÑиÑÑкÑ). ÐзбежаÑÑ Ð¾Ð¿ÐµÑаÑий оÑиÑÑки на пеÑеднем плане можно, ÑвелиÑивgin_pending_list_limitили пÑÐ¾Ð²Ð¾Ð´Ñ Ð°Ð²ÑооÑиÑÑÐºÑ Ð±Ð¾Ð»ÐµÐµ акÑивно. Ðднако еÑли вÑледÑÑвие ÑвелиÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ñога опеÑаÑии оÑиÑÑки запÑÑÑиÑÑÑ Ð¾ÑиÑÑка на пеÑеднем плане, она бÑÐ´ÐµÑ Ð²ÑполнÑÑÑÑÑ ÐµÑÑ Ð´Ð¾Ð»ÑÑе.ÐнаÑение
gin_pending_list_limitможно пеÑеопÑеделиÑÑ Ð´Ð»Ñ Ð¾ÑделÑнÑÑ Ð¸Ð½Ð´ÐµÐºÑов GIN, изменив Ð¸Ñ Ð¿Ð°ÑамеÑÑÑ Ñ ÑанениÑ, ÑÑо позволÑÐµÑ Ð·Ð°Ð´Ð°Ð²Ð°ÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ индекÑа GIN Ñвой поÑог оÑиÑÑки. ÐапÑимеÑ, можно ÑвелиÑиÑÑ Ð¿Ð¾Ñог ÑолÑко Ð´Ð»Ñ ÑаÑÑо обновлÑемÑÑ Ð¸Ð½Ð´ÐµÐºÑов GIN и оÑÑавиÑÑ ÐµÐ³Ð¾ низким Ð´Ð»Ñ Ð¾ÑÑалÑнÑÑ .- gin_fuzzy_search_limit
ÐÑновной ÑелÑÑ ÑазÑабоÑки индекÑов GIN бÑло обеÑпеÑиÑÑ Ð¿Ð¾Ð´Ð´ÐµÑÐ¶ÐºÑ Ñ Ð¾ÑоÑо ÑаÑÑиÑÑемого полноÑекÑÑового поиÑка в Postgres Pro, а пÑи полноÑекÑÑовом поиÑке неÑедко возникаÑÑ ÑиÑÑаÑии, когда возвÑаÑаеÑÑÑ Ð¾ÑÐµÐ½Ñ Ð±Ð¾Ð»ÑÑой Ð½Ð°Ð±Ð¾Ñ ÑезÑлÑÑаÑов. Ðднако ÑаÑе вÑего Ñак пÑоиÑÑ Ð¾Ð´Ð¸Ñ, когда запÑÐ¾Ñ ÑодеÑÐ¶Ð¸Ñ Ð¾ÑÐµÐ½Ñ ÑаÑÑо вÑÑÑеÑаÑÑиеÑÑ Ñлова, Ñак ÑÑо полÑÑеннÑй ÑезÑлÑÑÐ°Ñ Ð²ÑÑ Ñавно оказÑваеÑÑÑ Ð±ÐµÑполезнÑм. Так как ÑÑение множеÑÑва запиÑей Ñ Ð´Ð¸Ñка и поÑледÑÑÑÐ°Ñ ÑоÑÑиÑовка Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð½ÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ вÑемени, ÑÑо непÑиемлемо в пÑоизводÑÑвеннÑÑ ÑÑловиÑÑ . (ÐамеÑÑÑе, ÑÑо поиÑк по индекÑÑ Ð¿Ñи ÑÑом вÑполнÑеÑÑÑ Ð¾ÑÐµÐ½Ñ Ð±ÑÑÑÑо.)
ÐÐ»Ñ ÑпÑавлÑемого вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑÐ°ÐºÐ¸Ñ Ð·Ð°Ð¿ÑоÑов в GIN введено наÑÑÑаиваемое мÑгкое огÑаниÑение ÑвеÑÑ Ñ Ð´Ð»Ñ ÑиÑла возвÑаÑаемÑÑ ÑÑÑок: конÑигÑÑаÑионнÑй паÑамеÑÑ
gin_fuzzy_search_limit. Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð¾Ð½ Ñавен 0 (Ñо еÑÑÑ Ð¾Ð³ÑаниÑение оÑÑÑÑÑÑвÑеÑ). ÐÑли он Ð¸Ð¼ÐµÐµÑ Ð½ÐµÐ½Ñлевое знаÑение, возвÑаÑаемÑй Ð½Ð°Ð±Ð¾Ñ ÑÑÑок бÑÐ´ÐµÑ ÑлÑÑайно вÑбÑаннÑм подмножеÑÑвом вÑего набоÑа ÑезÑлÑÑаÑов.«ÐÑгким» оно назÑваеÑÑÑ Ð¿Ð¾ÑомÑ, ÑÑо ÑакÑиÑеÑкое ÑиÑло возвÑаÑаемÑÑ ÑÑÑок Ð¼Ð¾Ð¶ÐµÑ Ð½ÐµÑколÑко оÑлиÑаÑÑÑÑ Ð¾Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ знаÑениÑ, в завиÑимоÑÑи Ð¾Ñ Ð·Ð°Ð¿ÑоÑа и каÑеÑÑва ÑиÑÑемного генеÑаÑоÑа ÑлÑÑайнÑÑ ÑиÑел.
Ðз пÑакÑики, Ñо знаÑениÑми в неÑколÑко ÑÑÑÑÑ (напÑимеÑ, 5000 â 20000) полÑÑаÑÑÑÑ Ð¿ÑиемлемÑе ÑезÑлÑÑаÑÑ.
63.4.6. ÐгÑаниÑÐµÐ½Ð¸Ñ #
GIN полагаеÑ, ÑÑо индекÑиÑÑемÑе опеÑаÑоÑÑ ÑвлÑÑÑÑÑ ÑÑÑогими. ÐÑо ознаÑаеÑ, ÑÑо ÑÑнкÑÐ¸Ñ extractValue вовÑе не бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ Ð´Ð»Ñ Ð·Ð½Ð°Ñений NULL (вмеÑÑо ÑÑого бÑÐ´ÐµÑ Ð°Ð²ÑомаÑиÑеÑки ÑоздаваÑÑÑÑ Ð¿ÑÑÑÐ°Ñ Ð·Ð°Ð¿Ð¸ÑÑ Ð² индекÑе), Ñак же как и extractQuery не бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ Ñ Ð¸ÑкомÑм знаÑением NULL (пÑи ÑÑом ÑÑÐ°Ð·Ñ Ð¿ÑедполагаеÑÑÑ, ÑÑо запÑÐ¾Ñ Ð½Ðµ ÑдовлеÑвоÑÑеÑÑÑ). ÐамеÑÑÑе однако, ÑÑо пÑи ÑÑом поддеÑживаÑÑÑÑ ÐºÐ»ÑÑи NULL, ÑодеÑжаÑиеÑÑ Ð² ÑоÑÑавнÑÑ
обÑекÑаÑ
или иÑкомÑÑ
знаÑениÑÑ
.
63.4.7. ÐÑимеÑÑ #
РбазовÑй диÑÑÑибÑÑив Postgres Pro вклÑÑÐµÐ½Ñ ÐºÐ»Ð°ÑÑÑ Ð¾Ð¿ÐµÑаÑоÑов GIN, пеÑеÑиÑленнÑе Ñанее в ТаблиÑе 63.3. Также клаÑÑÑ Ð¾Ð¿ÐµÑаÑоÑов GIN ÑодеÑжаÑÑÑ Ð² ÑледÑÑÑиÑ
модÑлÑÑ
contrib:
btree_ginФÑнкÑионалÑноÑÑÑ B-деÑева Ð´Ð»Ñ ÑазлиÑнÑÑ Ñипов даннÑÑ
hstoreÐодÑÐ»Ñ Ð´Ð»Ñ Ñ ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ (клÑÑ, знаÑение)
intarrayРаÑÑиÑÐµÐ½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð´ÐµÑжка
int[]pg_trgmÐ¡Ñ Ð¾Ð¶ÐµÑÑÑ ÑекÑÑа на оÑнове ÑÑаÑиÑÑики ÑÑигÑамм