ProHoster > Blogs > AdministrÄcija > Datu bÄzes vaicÄjumu optimizÄÅ”ana, izmantojot B2B pakalpojuma piemÄru celtniekiem
Datu bÄzes vaicÄjumu optimizÄÅ”ana, izmantojot B2B pakalpojuma piemÄru celtniekiem
KÄ palielinÄt datubÄzes vaicÄjumu skaitu 10 reizes, nepÄrejot uz produktÄ«vÄku serveri, un uzturÄt sistÄmas funkcionalitÄti? Es jums pastÄstÄ«Å”u, kÄ mÄs tikÄm galÄ ar mÅ«su datu bÄzes veiktspÄjas samazinÄÅ”anos, kÄ optimizÄjÄm SQL vaicÄjumus, lai tie apkalpotu pÄc iespÄjas vairÄk lietotÄju un nepalielinÄtu skaitļoÅ”anas resursu izmaksas.
Veicu pakalpojumu biznesa procesu vadÄ«Å”anai bÅ«vniecÄ«bas uzÅÄmumos. Ar mums strÄdÄ apmÄram 3 tÅ«kstoÅ”i uzÅÄmumu. VairÄk nekÄ 10 tÅ«kstoÅ”i cilvÄku strÄdÄ ar mÅ«su sistÄmu katru dienu 4-10 stundas. Tas atrisina dažÄdas plÄnoÅ”anas, paziÅoÅ”anas, brÄ«dinÄÅ”anas, validÄcijas problÄmas... MÄs izmantojam PostgreSQL 9.6. Mums datu bÄzÄ ir aptuveni 300 tabulu un katru dienu tiek saÅemti lÄ«dz 200 miljoniem vaicÄjumu (10 tÅ«kstoÅ”i dažÄdu). VidÄji mums ir 3-4 tÅ«kstoÅ”i pieprasÄ«jumu sekundÄ, aktÄ«vÄkajos brīžos vairÄk nekÄ 10 tÅ«kstoÅ”i pieprasÄ«jumu sekundÄ. LielÄkÄ daļa vaicÄjumu ir OLAP. Ir daudz mazÄk papildinÄjumu, modifikÄciju un svÄ«trojumu, kas nozÄ«mÄ, ka OLTP slodze ir salÄ«dzinoÅ”i neliela. Es norÄdÄ«ju visus Å”os skaitļus, lai jÅ«s varÄtu novÄrtÄt mÅ«su projekta mÄrogu un saprast, cik noderÄ«ga jums var bÅ«t mÅ«su pieredze.
AttÄls viens. Lirisks
UzsÄkot izstrÄdi, mÄs Ä«sti nedomÄjÄm par to, kÄda slodze tiks pakļauta datu bÄzei un ko mÄs darÄ«tu, ja serveris pÄrtrauks vilkt. Veidojot datubÄzi, mÄs ievÄrojÄm vispÄrÄ«gus ieteikumus un centÄmies neieÅ”aut sev kÄjÄ, taÄu neievÄrojÄm vispÄrÄ«gus ieteikumus, piemÄram, "neizmantojiet modeli EntÄ«tijas atribÅ«tu vÄrtÄ«bas mÄs neiegÄjÄm. MÄs izstrÄdÄjÄm, pamatojoties uz normalizÄcijas principiem, izvairoties no datu dublÄÅ”anas un nerÅ«pÄjÄmies par noteiktu vaicÄjumu paÄtrinÄÅ”anu. TiklÄ«dz ieradÄs pirmie lietotÄji, mÄs saskÄrÄmies ar veiktspÄjas problÄmu. KÄ parasti, mÄs tam bijÄm pilnÄ«gi nesagatavoti. PirmÄs problÄmas izrÄdÄ«jÄs vienkÄrÅ”as. KÄ likums, viss tika atrisinÄts, pievienojot jaunu indeksu. Bet pienÄca laiks, kad vienkÄrÅ”i ielÄpi pÄrstÄja darboties. Saprotot, ka mums trÅ«kst pieredzes un mums kļūst arvien grÅ«tÄk saprast, kas izraisa problÄmas, nolÄ«gÄm speciÄlistus, kuri palÄ«dzÄja pareizi iestatÄ«t serveri, pieslÄgt uzraudzÄ«bu un parÄdÄ«ja, kur meklÄt. statistika.
Otrais attÄls. Statistikas
TÄtad mums ir aptuveni 10 tÅ«kstoÅ”i dažÄdu vaicÄjumu, kas tiek izpildÄ«ti mÅ«su datubÄzÄ dienÄ. No Å”iem 10 tÅ«kstoÅ”iem ir monstri, kas tiek izpildÄ«ti 2-3 miljonus reižu ar vidÄjo izpildes laiku 0.1-0.3 ms, un ir vaicÄjumi ar vidÄjo izpildes laiku 30 sekundes, kas tiek izsaukti 100 reizes dienÄ.
Nebija iespÄjams optimizÄt visus 10 tÅ«kstoÅ”us vaicÄjumu, tÄpÄc nolÄmÄm izdomÄt, kur likt pÅ«les, lai pareizi uzlabotu datu bÄzes veiktspÄju. PÄc vairÄkÄm iterÄcijÄm mÄs sÄkÄm dalÄ«t pieprasÄ«jumus pa veidiem.
TOP pieprasījumi
Å ie ir smagÄkie vaicÄjumi, kas aizÅem visvairÄk laika (kopÄjais laiks). Tie ir vaicÄjumi, kas tiek saukti vai nu ļoti bieži, vai arÄ« vaicÄjumi, kuru izpilde prasa ļoti ilgu laiku (ilgi un bieži vaicÄjumi tika optimizÄti pirmajÄs cÄ«Åas par Ätrumu iterÄcijÄs). TÄ rezultÄtÄ serveris visvairÄk laika pavada to izpildei. TurklÄt ir svarÄ«gi nodalÄ«t populÄrÄkos pieprasÄ«jumus pÄc kopÄjÄ izpildes laika un atseviŔķi pÄc IO laika. Å Ädu vaicÄjumu optimizÄÅ”anas metodes nedaudz atŔķiras.
Visu uzÅÄmumu ierastÄ prakse ir strÄdÄt ar TOP pieprasÄ«jumiem. To ir maz; pat viena vaicÄjuma optimizÄÅ”ana var atbrÄ«vot 5-10% resursu. TomÄr, projektam tuvojoties, TOP vaicÄjumu optimizÄÅ”ana kļūst par arvien nenozÄ«mÄ«gÄku uzdevumu. Visas vienkÄrÅ”Äs metodes jau ir izstrÄdÄtas, un āsmagÄkaisā pieprasÄ«jums aizÅem ātikaiā 3-5% resursu. Ja TOP vaicÄjumi kopumÄ aizÅem mazÄk nekÄ 30-40% laika, tad, visticamÄk, jÅ«s jau esat pielicis pÅ«les, lai tie darbotos Ätri, un ir pienÄcis laiks pÄriet uz nÄkamÄs grupas vaicÄjumu optimizÄÅ”anu.
Atliek atbildÄt uz jautÄjumu, cik populÄrÄko vaicÄjumu jÄiekļauj Å”ajÄ grupÄ. Es parasti Åemu vismaz 10, bet ne vairÄk kÄ 20. CenÅ”os nodroÅ”inÄt, lai TOP grupas pirmÄs un pÄdÄjÄs laiks atŔķirtos ne vairÄk kÄ 10 reizes. Tas ir, ja vaicÄjuma izpildes laiks strauji samazinÄs no 1. vietas uz 10., tad es Åemu TOP-10, ja kritums ir pakÄpeniskÄks, tad es palielinÄju grupas lielumu lÄ«dz 15 vai 20.
VidÄjie zemnieki
Tie visi ir pieprasÄ«jumi, kas nÄk uzreiz aiz TOP, izÅemot pÄdÄjos 5-10%. Parasti Å”o vaicÄjumu optimizÄÅ”ana slÄpjas iespÄja ievÄrojami palielinÄt servera veiktspÄju. Å o pieprasÄ«jumu svars var sasniegt 80%. Bet pat tad, ja to daļa ir pÄrsniegusi 50%, ir pienÄcis laiks tos aplÅ«kot rÅ«pÄ«gÄk.
Aste
KÄ minÄts, Å”ie vaicÄjumi parÄdÄs beigÄs un aizÅem 5ā10% laika. Par tiem varat aizmirst tikai tad, ja neizmantojat automÄtiskos vaicÄjumu analÄ«zes rÄ«kus, tad arÄ« to optimizÄÅ”ana var bÅ«t lÄta.
KÄ novÄrtÄt katru grupu?
Es izmantoju SQL vaicÄjumu, kas palÄ«dz veikt Å”Ädu PostgreSQL novÄrtÄjumu (esmu pÄrliecinÄts, ka lÄ«dzÄ«gu vaicÄjumu var uzrakstÄ«t arÄ« daudzÄm citÄm DBVS)
SQL vaicÄjums, lai novÄrtÄtu TOP-MEDIUM-TAIL grupu lielumu
SELECT sum(time_top) AS sum_top, sum(time_medium) AS sum_medium, sum(time_tail) AS sum_tail
FROM
(
SELECT CASE WHEN rn <= 20 THEN tt_percent ELSE 0 END AS time_top,
CASE WHEN rn > 20 AND rn <= 800 THEN tt_percent ELSE 0 END AS time_medium,
CASE WHEN rn > 800 THEN tt_percent ELSE 0 END AS time_tail
FROM (
SELECT total_time / (SELECT sum(total_time) FROM pg_stat_statements) * 100 AS tt_percent, query,
ROW_NUMBER () OVER (ORDER BY total_time DESC) AS rn
FROM pg_stat_statements
ORDER BY total_time DESC
) AS t
)
AS ts
VaicÄjuma rezultÄts ir trÄ«s kolonnas, no kurÄm katra satur procentuÄlo laiku, kas nepiecieÅ”ams Ŕīs grupas vaicÄjumu apstrÄdei. PieprasÄ«juma iekÅ”pusÄ ir divi cipari (manÄ gadÄ«jumÄ tas ir 20 un 800), kas atdala pieprasÄ«jumus no vienas grupas no citas.
LÅ«k, kÄ aptuveni salÄ«dzina pieprasÄ«jumu Ä«patsvaru optimizÄcijas darbu sÄkÅ”anas laikÄ un tagad.
DiagrammÄ redzams, ka strauji samazinÄjies TOP pieprasÄ«jumu Ä«patsvars, bet pieauguÅ”i āvidÄjie zemniekiā.
SÄkumÄ TOP pieprasÄ«jumos bija klajas kļūdas. Laika gaitÄ bÄrnu slimÄ«bas izzuda, TOP pieprasÄ«jumu Ä«patsvars samazinÄjÄs, un arvien vairÄk bija jÄpieliek pÅ«les, lai paÄtrinÄtu sarežģītus pieprasÄ«jumus.
Lai iegÅ«tu pieprasÄ«jumu tekstu, mÄs izmantojam Å”Ädu pieprasÄ«jumu
SELECT * FROM (
SELECT ROW_NUMBER () OVER (ORDER BY total_time DESC) AS rn, total_time / (SELECT sum(total_time) FROM pg_stat_statements) * 100 AS tt_percent, query
FROM pg_stat_statements
ORDER BY total_time DESC
) AS T
WHERE
rn <= 20 -- TOP
-- rn > 20 AND rn <= 800 -- MEDIUM
-- rn > 800 -- TAIL
Å eit ir saraksts ar visbiežÄk izmantotajÄm metodÄm, kas mums palÄ«dzÄja paÄtrinÄt TOP vaicÄjumu izpildi.
SistÄmas pÄrprojektÄÅ”ana, piemÄram, paziÅojumu loÄ£ikas pÄrstrÄdÄÅ”ana, izmantojot ziÅojumu brokeri, nevis periodiskus datu bÄzes vaicÄjumus
Indeksu pievienoŔana vai mainīŔana
ORM vaicÄjumu pÄrrakstÄ«Å”ana uz tÄ«ru SQL
Slinkas datu ielÄdes loÄ£ikas pÄrrakstÄ«Å”ana
KeÅ”atmiÅa, izmantojot datu denormalizÄciju. PiemÄram, mums ir tabulas savienojums PiegÄde -> RÄÄ·ins -> PieprasÄ«jums -> Pieteikums. Tas nozÄ«mÄ, ka katra piegÄde ir saistÄ«ta ar lietojumprogrammu, izmantojot citas tabulas. Lai nesaista visas tabulas katrÄ pieprasÄ«jumÄ, mÄs dublÄjÄm saiti uz pieprasÄ«jumu tabulÄ PiegÄde.
Statisko tabulu saglabÄÅ”ana keÅ”atmiÅÄ ar atsauces grÄmatÄm un reti mainÄmas tabulas programmas atmiÅÄ.
DažkÄrt izmaiÅas bija iespaidÄ«gas, taÄu tÄs nodroÅ”inÄja 5-10% no sistÄmas slodzes un bija pamatotas. Laika gaitÄ izplÅ«des gÄze kļuva arvien mazÄka, un bija nepiecieÅ”ama arvien nopietnÄka pÄrbÅ«ve.
Tad mÄs pievÄrsÄm uzmanÄ«bu otrajai pieprasÄ«jumu grupai - vidÄjo zemnieku grupai. TajÄ ir daudz vairÄk jautÄjumu, un Ŕķita, ka visas grupas analÄ«ze prasÄ«s daudz laika. TomÄr lielÄkÄ daļa vaicÄjumu izrÄdÄ«jÄs ļoti vienkÄrÅ”i optimizÄjami, un daudzas problÄmas tika atkÄrtotas desmitiem reižu dažÄdÄs variÄcijÄs. Å eit ir dažu tipisku optimizÄciju piemÄri, ko izmantojÄm desmitiem lÄ«dzÄ«gu vaicÄjumu, un katra optimizÄto vaicÄjumu grupa izlÄdÄja datubÄzi par 3ā5%.
TÄ vietÄ, lai pÄrbaudÄ«tu ierakstu esamÄ«bu, izmantojot COUNT un pilnu tabulas skenÄÅ”anu, sÄka izmantot EXISTS.
Tiku vaÄ¼Ä no DISTINCT (vispÄrÄjas receptes nav, bet dažreiz var viegli tikt vaļÄ, paÄtrinot pieprasÄ«jumu 10-100 reizes).
PiemÄram, vaicÄjuma vietÄ, lai atlasÄ«tu visus draiverus no lielas piegÄdes tabulas (PIEGÄDE)
SELECT DISTINCT P.ID, P.FIRST_NAME, P.LAST_NAME
FROM DELIVERY D JOIN PERSON P ON D.DRIVER_ID = P.ID
veica vaicÄjumu salÄ«dzinoÅ”i mazÄ tabulÄ PERSON
SELECT P.ID, P.FIRST_NAME, P.LAST_NAME
FROM PERSON
WHERE EXISTS(SELECT D.ID FROM DELIVERY WHERE D.DRIVER_ID = P.ID)
Å Ä·iet, ka mÄs izmantojÄm korelÄtu apakÅ”vaicÄjumu, taÄu tas paÄtrina vairÄk nekÄ 10 reizes.
Katrs konkrÄtais pieprasÄ«jums dažkÄrt tika paÄtrinÄts 3-1000 reizes. Neskatoties uz iespaidÄ«go veiktspÄju, sÄkumÄ mums Ŕķita, ka nav jÄgas optimizÄt vaicÄjumu, kura aizpildÄ«Å”ana aizÅem 10 ms, ir viens no 3. simts smagÄkajiem vaicÄjumiem un aizÅem simtdaļas no kopÄjÄ datu bÄzes ielÄdes laika. TaÄu, piemÄrojot vienu un to paÅ”u recepti viena veida vaicÄjumu grupai, mÄs atguvÄm dažus procentus. Lai netÄrÄtu laiku, manuÄli pÄrskatot visus simtiem vaicÄjumu, mÄs uzrakstÄ«jÄm vairÄkus vienkÄrÅ”us skriptus, kas izmantoja regulÄras izteiksmes, lai atrastu viena veida vaicÄjumus. TÄ rezultÄtÄ automÄtiska meklÄÅ”ana vaicÄjumu grupÄs ļÄva mums vÄl vairÄk uzlabot mÅ«su veiktspÄju ar pieticÄ«gÄm pÅ«lÄm.
RezultÄtÄ mÄs jau trÄ«s gadus strÄdÄjam pie vienas un tÄs paÅ”as aparatÅ«ras. VidÄjÄ dienas slodze ir aptuveni 30%, maksimumos tÄ sasniedz 70%. PieprasÄ«jumu skaits, kÄ arÄ« lietotÄju skaits ir pieaudzis aptuveni 10 reizes. Un tas viss, pateicoties pastÄvÄ«gai Å”o paÅ”u TOP-MEDIUM pieprasÄ«jumu grupu uzraudzÄ«bai. TiklÄ«dz TOP grupÄ parÄdÄs jauns pieprasÄ«jums, mÄs to nekavÄjoties analizÄjam un cenÅ”amies paÄtrinÄt. MÄs pÄrskatÄm grupu MEDIUM reizi nedÄļÄ, izmantojot vaicÄjumu analÄ«zes skriptus. Ja mÄs saskaramies ar jauniem vaicÄjumiem, kurus jau zinÄm, kÄ optimizÄt, mÄs tos Ätri mainÄm. Dažreiz mÄs atrodam jaunas optimizÄcijas metodes, kuras var piemÄrot vairÄkiem vaicÄjumiem vienlaikus.
PÄc mÅ«su prognozÄm, paÅ”reizÄjais serveris izturÄs lietotÄju skaita pieaugumu vÄl 3-5 reizes. Tiesa, mums ir vÄl viens dÅ«zis - mÄs joprojÄm neesam pÄrsÅ«tÄ«juÅ”i SELECT vaicÄjumus uz spoguli, kÄ ieteikts. Bet mÄs to nedarÄm apzinÄti, jo vispirms vÄlamies pilnÄ«bÄ izsmelt āgudrÄsā optimizÄcijas iespÄjas, pirms ieslÄdzam āsmago artilÄrijuā.
PaveiktÄ darba kritiska apskate var ieteikt izmantot vertikÄlo mÄrogoÅ”anu. PÄrciet jaudÄ«gÄku serveri, nevis tÄrÄjiet speciÄlistu laiku. Serveris var nemaksÄt tik dÄrgi, jo Ä«paÅ”i tÄpÄc, ka mÄs vÄl neesam izsmÄluÅ”i vertikÄlÄs mÄrogoÅ”anas robežas. TaÄu tikai pieprasÄ«jumu skaits pieauga 10 reizes. VairÄku gadu laikÄ sistÄmas funkcionalitÄte ir palielinÄjusies, un tagad ir vairÄk pieprasÄ«jumu veidu. Pateicoties keÅ”atmiÅai, esoÅ”Ä funkcionalitÄte tiek izpildÄ«ta ar mazÄku pieprasÄ«jumu skaitu un efektÄ«vÄkiem pieprasÄ«jumiem. Tas nozÄ«mÄ, ka varat droÅ”i reizinÄt ar vÄl 5, lai iegÅ«tu reÄlo paÄtrinÄjuma koeficientu. TÄtad, pÄc konservatÄ«vÄkajÄm aplÄsÄm, mÄs varam teikt, ka paÄtrinÄjums bija 50 vai vairÄk reižu. Servera vertikÄlÄ Å”Å«poÅ”ana izmaksÄtu 50 reizes vairÄk. ÄŖpaÅ”i Åemot vÄrÄ, ka pÄc optimizÄcijas tas darbojas visu laiku, un rÄÄ·ins par nomÄto serveri nÄk katru mÄnesi.