I kēia lā, ʻaʻohe hihia paʻakikī a me nā algorithm maʻalahi i SQL. E maʻalahi loa nā mea a pau, ma ka pae o Kāpena Obvious - e hana kāua ke nānā ʻana i ka papa inoa hanana hoʻokaʻawale ʻia e ka manawa.
ʻO ia hoʻi, aia kahi hōʻailona ma ka waihona events
, a he mahinaai kana ts
- ʻo ia ka manawa a mākou e makemake ai e hōʻike i kēia mau moʻolelo ma ke ʻano kūpono:
CREATE TABLE events(
id
serial
PRIMARY KEY
, ts
timestamp
, data
json
);
CREATE INDEX ON events(ts DESC);
Ua maopopo ʻaʻole mākou e loaʻa i kahi mau moʻolelo ma laila, no laila pono mākou i kekahi ʻano hoʻokele ʻaoʻao.
#0. "ʻO wau ka pogromist a koʻu makuahine"
cur.execute("SELECT * FROM events;")
rows = cur.fetchall();
rows.sort(key=lambda row: row.ts, reverse=True);
limit = 26
print(rows[offset:offset+limit]);
ʻAʻole ia he mea hoʻohenehene - he kakaikahi, akā loaʻa ma ka nahele. I kekahi manawa, ma hope o ka hana ʻana me ORM, hiki ke paʻakikī ke hoʻololi i ka hana "pololei" me SQL.
Akā, e neʻe kākou i nā pilikia maʻamau a emi ʻole.
#1. OFFSET
SELECT
...
FROM
events
ORDER BY
ts DESC
LIMIT 26 OFFSET $1; -- 26 - записей на странице, $1 - начало страницы
No hea mai ka helu 26? ʻO kēia ka helu kokoke o nā helu e hoʻopiha i hoʻokahi pale. ʻOi aku ka pololei, 25 hōʻike i nā moʻolelo, a me 1, e hōʻailona ana aia kekahi mea ʻē aʻe i loko o ka laʻana a he mea kūpono ke neʻe aku.
ʻOiaʻiʻo, ʻaʻole hiki ke "humuhumu" i kēia waiwai i loko o ke kino o ka noi, akā hele i kahi ʻāpana. Akā i kēia hihia, ʻaʻole hiki i ka mea hoʻonohonoho PostgreSQL ke hilinaʻi i ka ʻike he liʻiliʻi nā moʻolelo - a koho maʻalahi i kahi hoʻolālā kūpono ʻole.
A ʻoiai i loko o ka ʻaoʻao noi, ʻike ʻia ka nānā ʻana i ke kākau inoa e like me ka hoʻololi ʻana ma waena o nā "ʻaoʻao" ʻike, ʻaʻohe mea i ʻike i kekahi mea kānalua no ka manawa lōʻihi. A hiki i ka manawa, i ka hakakā ʻana no ka maʻalahi, ua hoʻoholo ʻo UI/UX e hana hou i ka interface i ka "scroll endless scroll" - ʻo ia hoʻi, ua huki ʻia nā mea kākau inoa āpau i kahi papa inoa e hiki ai i ka mea hoʻohana ke ʻōwili i luna a i lalo.
A no laila, i ka wā o ka hoʻāʻo aʻe, ua hopu ʻia ʻoe ka lua o na mooolelo ma ka papa inoa. No ke aha, no ka mea, he index maʻamau ka papaʻaina (ts)
, e hilina'i nei kāu nīnau?
No ka mea ʻaʻole ʻoe i noʻonoʻo i kēlā ts
ʻaʻole ia he kī kū hoʻokahi ma keia papaaina. ʻOiaʻiʻo, a ʻAʻole kū hoʻokahi kāna mau waiwai, e like me kēlā me kēia "manawa" i nā kūlana maoli - no laila, ʻo ka moʻolelo like i loko o nā nīnau pili ʻelua e "lele" maʻalahi mai kahi ʻaoʻao a i kahi ʻaoʻao ma muli o kahi kauoha hope ʻē aʻe i loko o ke ʻano o ka hoʻokaʻawale ʻana i ka waiwai kī like.
ʻOiaʻiʻo, aia kekahi pilikia lua i hūnā ʻia ma aneʻi, ʻoi aku ka paʻakikī o ka ʻike - ʻaʻole e hōʻike ʻia kekahi mau helu i nā mea āpau! Ma hope o nā mea a pau, ua lawe nā moʻolelo "ʻelua" i kahi o kekahi. Hiki ke loaʻa kahi wehewehe kikoʻī me nā kiʻi nani
Ka hoʻonui ʻana i ka papa kuhikuhi
Hoʻomaopopo ka mea hoʻomohala maalea e pono ke hana kūʻokoʻa ke kī kuhikuhi, a ʻo ke ala maʻalahi ka hoʻonui ʻana me kahi kahua kūʻokoʻa maopopo, kahi kūpono o PK no:
CREATE UNIQUE INDEX ON events(ts DESC, id DESC);
A hoʻololi ke noi:
SELECT
...
ORDER BY
ts DESC, id DESC
LIMIT 26 OFFSET $1;
#2. E hoʻololi i nā "cursors"
Ma hope o kekahi manawa, hiki mai kahi DBA iā ʻoe a "ʻoluʻolu" i kāu mau noi
SELECT
...
WHERE
(ts, id) < ($1, $2) -- последние полученные на предыдущем шаге значения
ORDER BY
ts DESC, id DESC
LIMIT 26;
Ua hanu ʻoe i ka ʻoluʻolu a hiki mai ...
#3. Hoʻomaʻemaʻe i nā kuhikuhi
No ka mea i kekahi lā heluhelu kāu DBA (ts DESC)
.
Akā he aha ka mea e hana ai me ka pilikia mua o ka "lele" moʻolelo ma waena o nā ʻaoʻao?
Ma keʻano laulā, ʻo wai ka mea e pāpā iā mākou e heluhelu ʻaʻole "26 pololei", akā "ʻaʻole emi ma lalo o 26"? No ka laʻana, i loko o ka poloka aʻe aia nā moʻolelo me nā manaʻo like ʻole ts
- a laila, ʻaʻohe pilikia me ka "lele" moʻolelo ma waena o nā poloka!
Eia pehea e hoʻokō ai i kēia:
SELECT
...
WHERE
ts < $1 AND
ts >= coalesce((
SELECT
ts
FROM
events
WHERE
ts < $1
ORDER BY
ts DESC
LIMIT 1 OFFSET 25
), '-infinity')
ORDER BY
ts DESC;
He aha ka hana ma ʻaneʻi?
- Hoʻopaʻa mākou i nā moʻolelo 25 "lalo" a loaʻa ka waiwai "palena".
ts
. - Inā ʻaʻohe mea ma laila, e hoʻololi i ka waiwai NULL me
-infinity
. - Wehe mākou i ka ʻāpana holoʻokoʻa o nā waiwai ma waena o ka waiwai i loaʻa
ts
a ua hala ka ʻāpana $1 mai ke kikowaena (ka waiwai i hāʻawi ʻia "hope" mua). - Inā hoʻihoʻi ʻia kahi poloka me ka liʻiliʻi o 26 mau moʻolelo, ʻo ia ka mea hope loa.
A i ʻole ke kiʻi like:
No ka mea i kēia manawa ua loaʻa iā mākou ʻaʻohe "hoʻomaka" kikoʻī o ka hāpana, a laila ʻaʻohe mea e pale iā mākou mai ka "hoʻonui" i kēia noi ma ka ʻaoʻao ʻē aʻe a me ka hoʻokō ʻana i ka hoʻouka ikaika ʻana o nā poloka ʻikepili mai ka "helu kuhikuhi" ma nā ʻaoʻao ʻelua - i lalo a i luna.
Kākau
- ʻAe, i kēia hihia ke komo mākou i ka index ʻelua, akā ʻo nā mea āpau "ma ka index". No laila, he subquery wale nō ka hopena i hoʻokahi hou Index Only Scan.
- ʻIke maopopo loa hiki ke hoʻohana ʻia kēia ʻenehana inā loaʻa iā ʻoe nā waiwai
ts
hiki ke hele ma ka manawa wale nō, a aole nui o lakou. Inā ʻo kāu hihia maʻamau "he miliona mau moʻolelo ma 00:00:00.000", ʻaʻole pono ʻoe e hana i kēia. ʻO kaʻu manaʻo, ʻaʻole pono ʻoe e ʻae i kēlā hihia e hana. Akā inā loaʻa kēia, e hoʻohana i ke koho me kahi kuhikuhi lōʻihi.
Source: www.habr.com