PostgreSQL ನ ಆಂತರಿಕ ಕಾರ್ಯವಿಧಾನಗಳ ವಿಶಿಷ್ಟತೆಗಳು ಕೆಲವು ಸಂದರ್ಭಗಳಲ್ಲಿ ಇದು ತುಂಬಾ ವೇಗವಾಗಿರಲು ಮತ್ತು ಇತರರಲ್ಲಿ "ಅತ್ಯಂತ ವೇಗವಾಗಿಲ್ಲ" ಎಂದು ಅನುಮತಿಸುತ್ತದೆ. ಇಂದು ನಾವು DBMS ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಡೆವಲಪರ್ ಅದರೊಂದಿಗೆ ಏನು ಮಾಡುತ್ತಾನೆ ಎಂಬುದರ ನಡುವಿನ ಸಂಘರ್ಷದ ಒಂದು ಶ್ರೇಷ್ಠ ಉದಾಹರಣೆಯ ಮೇಲೆ ಕೇಂದ್ರೀಕರಿಸುತ್ತೇವೆ - ಅಪ್ಡೇಟ್ ವಿರುದ್ಧ MVCC ತತ್ವಗಳು.
ನಿಂದ ಸಂಕ್ಷಿಪ್ತ ಕಥೆ
UPDATE ಆಜ್ಞೆಯಿಂದ ಸಾಲನ್ನು ಮಾರ್ಪಡಿಸಿದಾಗ, ಎರಡು ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ವಾಸ್ತವವಾಗಿ ನಿರ್ವಹಿಸಲಾಗುತ್ತದೆ: DELETE ಮತ್ತು INSERT. IN ಸ್ಟ್ರಿಂಗ್ನ ಪ್ರಸ್ತುತ ಆವೃತ್ತಿ xmax ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಿದ ವಹಿವಾಟಿನ ಸಂಖ್ಯೆಗೆ ಸಮನಾಗಿ ಹೊಂದಿಸಲಾಗಿದೆ. ನಂತರ ಅದನ್ನು ರಚಿಸಲಾಗಿದೆ ಹೊಸ ಆವೃತ್ತಿ ಅದೇ ಸಾಲು; ಅದರ xmin ಮೌಲ್ಯವು ಹಿಂದಿನ ಆವೃತ್ತಿಯ xmax ಮೌಲ್ಯದೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುತ್ತದೆ.
ಈ ವಹಿವಾಟು ಪೂರ್ಣಗೊಂಡ ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ, ಹಳೆಯ ಅಥವಾ ಹೊಸ ಆವೃತ್ತಿಯನ್ನು ಅವಲಂಬಿಸಿ COMMIT/ROOLBACK
, ಗುರುತಿಸಲಾಗುವುದು "ಸತ್ತ" (ಸತ್ತ ಟುಪಲ್ಸ್) ಹಾದುಹೋಗುವಾಗ VACUUM
ಮೇಜಿನ ಪ್ರಕಾರ ಮತ್ತು ತೆರವುಗೊಳಿಸಲಾಗಿದೆ.
ಆದರೆ ಇದು ಈಗಿನಿಂದಲೇ ಆಗುವುದಿಲ್ಲ, ಆದರೆ “ಸತ್ತವರ” ಸಮಸ್ಯೆಗಳನ್ನು ಬಹಳ ಬೇಗನೆ ಸ್ವಾಧೀನಪಡಿಸಿಕೊಳ್ಳಬಹುದು - ಪುನರಾವರ್ತಿತ ಅಥವಾ
#1: ನಾನು ಅದನ್ನು ಸರಿಸಲು ಇಷ್ಟಪಡುತ್ತೇನೆ
ನಿಮ್ಮ ವಿಧಾನವು ವ್ಯವಹಾರ ತರ್ಕದಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿದೆ ಎಂದು ಹೇಳೋಣ ಮತ್ತು ಕೆಲವು ದಾಖಲೆಗಳಲ್ಲಿ X ಕ್ಷೇತ್ರವನ್ನು ನವೀಕರಿಸುವುದು ಅಗತ್ಯವೆಂದು ಅದು ಇದ್ದಕ್ಕಿದ್ದಂತೆ ಅರಿತುಕೊಳ್ಳುತ್ತದೆ:
UPDATE tbl SET X = <newX> WHERE pk = $1;
ನಂತರ, ಮರಣದಂಡನೆ ಮುಂದುವರೆದಂತೆ, Y ಕ್ಷೇತ್ರವನ್ನು ಸಹ ನವೀಕರಿಸಬೇಕು ಎಂದು ಅದು ತಿರುಗುತ್ತದೆ:
UPDATE tbl SET Y = <newY> WHERE pk = $1;
... ಮತ್ತು ನಂತರ Z - ಏಕೆ ಟ್ರೈಫಲ್ಸ್ ಮೇಲೆ ಸಮಯ ವ್ಯರ್ಥ?
UPDATE tbl SET Z = <newZ> WHERE pk = $1;
ನಾವು ಈಗ ಡೇಟಾಬೇಸ್ನಲ್ಲಿ ಈ ದಾಖಲೆಯ ಎಷ್ಟು ಆವೃತ್ತಿಗಳನ್ನು ಹೊಂದಿದ್ದೇವೆ? ಹೌದು, 4 ತುಣುಕುಗಳು! ಇವುಗಳಲ್ಲಿ, ಒಂದು ಸಂಬಂಧಿತವಾಗಿದೆ ಮತ್ತು 3 ಅನ್ನು ನಿಮ್ಮ ನಂತರ [ಸ್ವಯಂ] ವ್ಯಾಕ್ಯೂಮ್ ಮೂಲಕ ಸ್ವಚ್ಛಗೊಳಿಸಬೇಕಾಗುತ್ತದೆ.
ಈ ರೀತಿ ಮಾಡಬೇಡಿ! ಬಳಸಿ ಒಂದು ವಿನಂತಿಯಲ್ಲಿ ಎಲ್ಲಾ ಕ್ಷೇತ್ರಗಳನ್ನು ನವೀಕರಿಸಲಾಗುತ್ತಿದೆ - ಯಾವಾಗಲೂ ವಿಧಾನದ ತರ್ಕವನ್ನು ಈ ರೀತಿ ಬದಲಾಯಿಸಬಹುದು:
UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;
#2: ಬಳಕೆ ಭಿನ್ನವಾಗಿದೆ, ಲ್ಯೂಕ್!
ಆದ್ದರಿಂದ, ನೀವು ಇನ್ನೂ ಬಯಸಿದ್ದೀರಿ
UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;
ಸರಿಸುಮಾರು ಈ ಫಾರ್ಮ್ನಲ್ಲಿ ವಿನಂತಿಯು ಆಗಾಗ್ಗೆ ಸಂಭವಿಸುತ್ತದೆ ಮತ್ತು ಯಾವಾಗಲೂ ಖಾಲಿ ಹೊಸ ಕ್ಷೇತ್ರವನ್ನು ಭರ್ತಿ ಮಾಡಲು ಅಲ್ಲ, ಆದರೆ ಡೇಟಾದಲ್ಲಿನ ಕೆಲವು ದೋಷಗಳನ್ನು ಸರಿಪಡಿಸಲು. ಅದೇ ಸಮಯದಲ್ಲಿ, ಅವಳು ಸ್ವತಃ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಡೇಟಾದ ನಿಖರತೆಯನ್ನು ಗಣನೆಗೆ ತೆಗೆದುಕೊಳ್ಳುವುದಿಲ್ಲ - ಆದರೆ ವ್ಯರ್ಥ! ಅಂದರೆ, ದಾಖಲೆಯನ್ನು ಪುನಃ ಬರೆಯಲಾಗಿದೆ, ಅದರಲ್ಲಿ ನಿಖರವಾಗಿ ಏನನ್ನು ಹೊಂದಿದ್ದರೂ ಸಹ - ಆದರೆ ಏಕೆ? ಅದನ್ನು ಸರಿಪಡಿಸೋಣ:
UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;
ಅಂತಹ ಅದ್ಭುತ ಆಪರೇಟರ್ ಅಸ್ತಿತ್ವದ ಬಗ್ಗೆ ಅನೇಕ ಜನರಿಗೆ ತಿಳಿದಿಲ್ಲ, ಆದ್ದರಿಂದ ಇಲ್ಲಿ ಚೀಟ್ ಶೀಟ್ ಇದೆ IS DISTINCT FROM
ಮತ್ತು ಸಹಾಯ ಮಾಡಲು ಇತರ ತಾರ್ಕಿಕ ನಿರ್ವಾಹಕರು:
ಮತ್ತು ಸಂಕೀರ್ಣ ಕಾರ್ಯಾಚರಣೆಗಳ ಬಗ್ಗೆ ಸ್ವಲ್ಪ ROW()
- ಅಭಿವ್ಯಕ್ತಿಗಳು:
#3: ನಾನು ನನ್ನ ಪ್ರಿಯತಮೆಯನ್ನು ಗುರುತಿಸುವ ಮೂಲಕ... ನಿರ್ಬಂಧಿಸುವುದು
ಬಿಡುಗಡೆ ಮಾಡಲಾಗುತ್ತಿದೆ ಎರಡು ಒಂದೇ ಸಮಾನಾಂತರ ಪ್ರಕ್ರಿಯೆಗಳು, ಪ್ರತಿಯೊಂದೂ ನಮೂದನ್ನು "ಪ್ರಗತಿಯಲ್ಲಿದೆ" ಎಂದು ಗುರುತಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತದೆ:
UPDATE tbl SET processing = TRUE WHERE pk = $1;
ಈ ಪ್ರಕ್ರಿಯೆಗಳು ವಾಸ್ತವವಾಗಿ ಪರಸ್ಪರ ಸ್ವತಂತ್ರವಾಗಿ ಕೆಲಸಗಳನ್ನು ಮಾಡಿದರೂ, ಆದರೆ ಅದೇ ID ಯೊಳಗೆ, ಮೊದಲ ವಹಿವಾಟು ಪೂರ್ಣಗೊಳ್ಳುವವರೆಗೆ ಎರಡನೇ ಕ್ಲೈಂಟ್ ಈ ವಿನಂತಿಯ ಮೇಲೆ "ಲಾಕ್" ಆಗಿರುತ್ತದೆ.
ಪರಿಹಾರ #1: ಕಾರ್ಯವನ್ನು ಹಿಂದಿನದಕ್ಕೆ ಕಡಿಮೆ ಮಾಡಲಾಗಿದೆ
ಅದನ್ನು ಮತ್ತೆ ಸೇರಿಸೋಣ IS DISTINCT FROM
:
UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;
ಈ ರೂಪದಲ್ಲಿ, ಎರಡನೇ ವಿನಂತಿಯು ಡೇಟಾಬೇಸ್ನಲ್ಲಿ ಏನನ್ನೂ ಬದಲಾಯಿಸುವುದಿಲ್ಲ, ಎಲ್ಲವೂ ಈಗಾಗಲೇ ಆಗಿರಬೇಕು - ಆದ್ದರಿಂದ, ನಿರ್ಬಂಧಿಸುವುದು ಸಂಭವಿಸುವುದಿಲ್ಲ. ಮುಂದೆ, ಅನ್ವಯಿಕ ಅಲ್ಗಾರಿದಮ್ನಲ್ಲಿ ದಾಖಲೆಯನ್ನು "ಕಂಡುಹಿಡಿಯದಿರುವ" ಅಂಶವನ್ನು ನಾವು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುತ್ತೇವೆ.
ಪರಿಹಾರ #2: ಸಲಹಾ ಬೀಗಗಳು
ಪ್ರತ್ಯೇಕ ಲೇಖನಕ್ಕಾಗಿ ದೊಡ್ಡ ವಿಷಯ, ಅದರಲ್ಲಿ ನೀವು ಓದಬಹುದು
ಪರಿಹಾರ #3: ಮೂರ್ಖ ಕರೆಗಳು
ಆದರೆ ಇದು ನಿಮಗೆ ನಿಖರವಾಗಿ ಏನಾಗಬೇಕು ಅದೇ ದಾಖಲೆಯೊಂದಿಗೆ ಏಕಕಾಲಿಕ ಕೆಲಸ? ಅಥವಾ ಕ್ಲೈಂಟ್ ಬದಿಯಲ್ಲಿ ವ್ಯಾಪಾರ ತರ್ಕವನ್ನು ಕರೆಯುವ ಅಲ್ಗಾರಿದಮ್ಗಳೊಂದಿಗೆ ನೀವು ಗೊಂದಲಕ್ಕೊಳಗಾಗಿದ್ದೀರಾ, ಉದಾಹರಣೆಗೆ? ಮತ್ತು ನೀವು ಅದರ ಬಗ್ಗೆ ಯೋಚಿಸಿದರೆ? ..
ಮೂಲ: www.habr.com