Iam plus quam 6000 vicibus usus es, sed una pluma habilis quae fortasse non latuit est structuram principalem extarede quo vide aliquid simile;
Audi illos, et petitiones tuae "lenis et sericeus fiet." π
Sed graviter, multae condiciones quae rogant tardum et promptum esurientem sunt typicam et cognosci potest structura et notitia consilii.
Hoc in casu, unusquisque homo elit optionem optimam in se quaerere non debet, sola eius experientia fretus - dicere ei possumus quid hic agatur, quid sit ratio; quam accedere ad solutionem. Id fecimus.
Ad has causas propius inspiciamus - quomodo definiantur et quae commendationes ducunt.
Ut melius te in themate immergas, primum potes audire truncum respondentem e mea fama apud PGConf.Russia 2020et tunc demum progrediuntur ad accuratam cuiusque exempli analysim:
Etiam in tali exemplo primitivo - 8.5 temporibus citius ac XXXIII temporibus paucioribus legit. Quo magis res "pro unoquoque valore" habes, eo manifestius effectum fk.
Adnoto talem indicem operari ut "praepositionem" indicem non deteriorem quam ante in aliis quaestionibus cum fk, ubi digerere pk non erat et non est (plus de hoc legere potes in meo articulo de inveniendo inefficax indexes). Complectens, normalis providebit expressa aliena clavis auxilio in hoc campo.
#2: index intersectio (BitmapAnd)
cum facit
Monstra omnia pacta clienti "LLC Kolokolchik", conclusa pro "NAO Buttercup".
Quam ad identify?
-> BitmapAnd
-> Bitmap Index Scan
-> Bitmap Index Scan
suasiones
partum compositum index per prata ab utroque originali vel unum capitulum entium cum pratis de secundo.
exempli gratia:
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ΡΠ°ΠΊΡΠΎΠ²"
, (random() * 100)::integer fk_org -- 100 ΡΠ°Π·Π½ΡΡ Π²Π½Π΅ΡΠ½ΠΈΡ ΠΊΠ»ΡΡΠ΅ΠΉ
, (random() * 1000)::integer fk_cli; -- 1K ΡΠ°Π·Π½ΡΡ Π²Π½Π΅ΡΠ½ΠΈΡ ΠΊΠ»ΡΡΠ΅ΠΉ
CREATE INDEX ON tbl(fk_org); -- ΠΈΠ½Π΄Π΅ΠΊΡ Π΄Π»Ρ foreign key
CREATE INDEX ON tbl(fk_cli); -- ΠΈΠ½Π΄Π΅ΠΊΡ Π΄Π»Ρ foreign key
SELECT
*
FROM
tbl
WHERE
(fk_org, fk_cli) = (1, 999); -- ΠΎΡΠ±ΠΎΡ ΠΏΠΎ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΉ ΠΏΠ°ΡΠ΅
(
SELECT
*
FROM
tbl
WHERE
fk_own = 1 -- ΡΠ½Π°ΡΠ°Π»Π° "ΡΠ²ΠΎΠΈ" 20
ORDER BY
pk
LIMIT 20
)
UNION ALL
(
SELECT
*
FROM
tbl
WHERE
fk_own IS NULL -- ΠΏΠΎΡΠΎΠΌ "Π½ΠΈΡΡΠΈ" 20
ORDER BY
pk
LIMIT 20
)
LIMIT 20; -- Π½ΠΎ Π²ΡΠ΅Π³ΠΎ - 20, Π±ΠΎΠ»ΡΡΠ΅ ΠΈ Π½Π΅ Π½Π°Π΄ΠΎ
Nos eo quod omnes 20 tabulae inquisitae statim in primo trunco ββreceptae sunt, ita secunda, cum magis "pretiosa" Bitmap acervo Scan, ne in fine quidem exsecutus est. 22x citius, 44x pauciores legit!
Create [more] specialized index ubi conditio aut additis agris in indice.
Si conditio colum est "stabilis" ad proposita tua - hoc est non importat expansionem index valorum in futuro - melius est uti WHERE index. Varii statuses boolean/enum huic categoriae bene conveniunt.
Si conditio eliquare non potest accipere de diversis significationibusergo melius est cum his agris indicem amplificare - sicut in situ cum BitmapAnd supra.
exempli gratia:
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ΡΠ°ΠΊΡΠΎΠ²"
, CASE
WHEN random() < 1::real/16 THEN NULL
ELSE (random() * 100)::integer -- 100 ΡΠ°Π·Π½ΡΡ Π²Π½Π΅ΡΠ½ΠΈΡ ΠΊΠ»ΡΡΠ΅ΠΉ
END fk_own
, (random() < 1::real/50) critical; -- 1:50, ΡΡΠΎ Π·Π°ΡΠ²ΠΊΠ° "ΠΊΡΠΈΡΠΈΡΠ½Π°Ρ"
CREATE INDEX ON tbl(pk);
CREATE INDEX ON tbl(fk_own, pk);
SELECT
*
FROM
tbl
WHERE
critical
ORDER BY
pk
LIMIT 20;
Ut videre potes, eliquatio e consilio penitus evanuit et petitio facta est V temporibus citius.
#5:
cum facit
Varii conatus ad negotium tuum processui queue creandum, cum magnus numerus tabularum updates/deletionum in mensa ducunt ad rerum condicionem permultarum "mortuarum" monumentorum.
Prope inspice structuram indicis adhibitae et clavium agrorum in interrogatione - maxime probabile pars indicem non est certa. Verisimile erit tibi similem indicem creare, sine praepositione agrorum vel discere ad iterandum ipsorum values.
Omnia denique videntur etiam secundum indicem, sed suspecta quodammodo est - pro singulis viginti libris legitur, habuimus detrahere 20 paginas notitiarum, 4KB per recordum - nonne audax est? Nomen autem index tbl_fk_org_fk_cli_idx cogitatione exasperans.
Processus unius temporis (volutationis vel singularizationis) ex permultis monumentis in memoriam hoc partita non convenit.
Quam ad identify?
-> *
&& temp written > 0
suasiones
Si quantitas memoriae ab operatione adhibita non multum excedit valorem determinatum parametri work_memid emendandum est. Protinus in config pro omnibus potes, vel per potes SET [LOCAL] ad specifica petitionem / transaction.
exempli gratia:
SHOW work_mem;
-- "16MB"
SELECT
random()
FROM
generate_series(1, 1000000)
ORDER BY
1;
Ob rationes manifestas, si memoria tantum adhibetur et non disco, quaesitio multo citius exsecuta erit. Eodem tempore etiam pars oneris ab HDD tollitur.
Sed intelligere debes quod sortes et sortes memoriae semper collocare non possis - simpliciter omnibus satis non erit.
#9: irrelevant statistics
cum facit
Multum in datorum statim effuderunt, sed illud tempus non fuit ANALYZE.
Quam ad identify?
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& ratio >> 10
Exspectata erat cincinno a petitione certandi imposito vel copiae ferrariae CPU/hypervisoris insufficiens erant.
Quam ad identify?
-> *
&& (shared hit / 8K) + (shared read / 1K) < time / 1000
-- RAM hit = 64MB/s, HDD read = 8MB/s
&& time > 100ms -- ΡΠΈΡΠ°Π»ΠΈ ΠΌΠ°Π»ΠΎ, Π½ΠΎ ΡΠ»ΠΈΡΠΊΠΎΠΌ Π΄ΠΎΠ»Π³ΠΎ
suasiones
Utere externum magna ratio server consequat vel alius resource consummatio. Iam locuti sumus de nostra versione ordinandi hunc processum pro centum servientibus hic ΠΈ hic.