DuckDB vs SQLite: எதை எப்போது பயன்படுத்துவது?
SQLite என்பது transactional தரவுகளுக்கானது, DuckDB என்பது analytics பணிகளுக்கானது. ஒரே VPS-ல் இரண்டையும் எவ்வாறு திறம்பட பயன்படுத்துவது என்பதற்கான விளக்கமான வழிகாட்டி இதோ.
DuckDB மற்றும் SQLite: server-ல் எதைப் பயன்படுத்துவது என்பதற்கான ஒரே வரி பதில்
SQLite என்பது ஒரு OLTP (online transaction processing) engine ஆகும்: இது தரவுகளை வரிசைகளாக (rows) சேமிக்கிறது, மேலும் சில தரவுகளை மட்டும் விரைவாகவும் பாதுகாப்பாகவும் படிக்கவும் எழுதவும் வடிவமைக்கப்பட்டுள்ளது. DuckDB என்பது ஒரு OLAP (online analytical processing) engine ஆகும்: இது தரவுகளை நெடுவரிசைகளாக (columns) சேமிக்கிறது, மேலும் லட்சக்கணக்கான வரிசைகளை ஸ்கேன் செய்து ஒரு தொகுப்பு முடிவை (aggregate) வழங்க வடிவமைக்கப்பட்டுள்ளது. இவை இரண்டுமே embedded libraries ஆகும், இரண்டுமே ஒரு சாதாரண கோப்பைத் திறக்கின்றன, மேலும் இரண்டிற்கும் நீங்கள் தனியாக நிர்வகிக்க வேண்டிய server process எதுவும் இல்லை.
எனவே, "எதை தேர்வு செய்வது" என்ற கேள்விக்கு உண்மையான பதில் பெரும்பாலும் "இரண்டையும், ஒரே VPS-ல் பயன்படுத்துங்கள்" என்பதுதான். உங்கள் application-ன் நேரடித் தரவுகளை (live state) SQLite-ல் வைத்துக்கொள்ளுங்கள். உங்கள் reporting பணிகளுக்கு DuckDB மூலம் Parquet மற்றும் CSV கோப்புகளைப் படியுங்கள். இவை இரண்டும் வெவ்வேறு பணிகளைச் செய்வதால், அவற்றுக்கிடையே போட்டி இல்லை.
Row storage மற்றும் column storage ஏன் பதிலில் மாற்றத்தை ஏற்படுத்துகிறது
SQLite ஒரு row-ஐ ஒரு பக்கத்தின் (page) தொடர்ச்சியான பகுதியாக எழுதுகிறது. ஒரு order-ஐ அதன் primary key மூலம் எடுக்கும்போது, ஒரு index page மற்றும் ஒரு data page என மொத்தம் இரண்டு முறை மட்டுமே படிக்கப்படுகிறது. ஒரு application வினாடிக்கு ஆயிரக்கணக்கான முறை செய்யும் செயல் இதுதான்: இந்த user-ஐப் படி, இந்த session-ஐ update செய், இந்த order-ஐ insert செய்.
DuckDB ஒவ்வொரு column-ஐயும் தனித்தனியாக எழுதி அவற்றைச் சுருக்குகிறது (compress). ஐந்து மில்லியன் rows-ல் amount_cents-ஐக் கூட்டும்போது, அது amount_cents column-ஐ மட்டுமே படிக்கிறது, கோப்பில் உள்ள மற்ற அனைத்து bytes-களையும் தவிர்க்கிறது, மேலும் மதிப்புகளின் தொகுதிகளுக்கு (batches) vectorised code மூலம் கூட்டல் செய்கிறது. மற்ற columns வட்டில் (disk) இருந்து படிக்கப்படுவதே இல்லை; இதனால்தான் வேகம் கிடைக்கிறது.
இப்போது ஒவ்வொரு engine-ஐயும் மற்றொன்றின் பணிச்சுமைக்கு (workload) உட்படுத்திப் பாருங்கள். ஒரு column-ஐக் கூட்டும்போது SQLite ஒவ்வொரு row-ஆகச் சென்று, ஒரு field-ஐ அடைய முழு row-ஐயும் பக்கத்திலிருந்து எடுக்க வேண்டியுள்ளது, எனவே அது தேவைக்கு அதிகமாக வட்டில் படிக்கிறது. ஒரு order-ஐ insert செய்யும்போது DuckDB ஒவ்வொரு column-ன் சேமிப்பகத்தையும் தொட வேண்டியுள்ளது, மேலும் அவ்வாறு செய்ய முழு database கோப்பின் மீதும் write lock எடுக்கிறது. எந்த engine-ம் பழுதடையவில்லை. ஒவ்வொன்றும் தனக்காக வடிவமைக்கப்படாத ஒரு கேள்விக்கு விடையளிக்க முயல்கின்றன.
SQLite எப்போது சிறந்தது: பரிவர்த்தனை சார்ந்த application நிலை
எழுதும் செயல்பாடுகள் சிறியதாகவும், அடிக்கடி நிகழக்கூடியதாகவும், அதே சமயம் இழக்கப்படக்கூடாததாகவும் இருக்கும்போது SQLite-ஐத் தேர்ந்தெடுக்கவும். Sessions, orders, queue வரிசைகள், settings என web request மூலம் உருவாக்கப்படும் எதற்கும் இது பொருந்தும்.
sudo apt update && sudo apt install -y sqlite3
sudo install -d -o "$USER" -g "$USER" /srv/appஅட்டவணையை உருவாக்கி, அதே கட்டத்தில் write-ahead logging-ஐ இயக்கவும்.
sqlite3 /srv/app/app.db <<'SQL'
PRAGMA journal_mode = WAL;
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY,
customer TEXT NOT NULL,
placed_at TEXT NOT NULL,
amount_cents INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS orders_customer ON orders (customer);
INSERT INTO orders (customer, placed_at, amount_cents)
VALUES ('ana', '2026-07-30T09:14:00Z', 4200);
SQLவெளியீட்டின் முதல் வரி wal ஆகும். இது தான் மாறிய பயன்முறையை (mode) அறிவிக்கும் PRAGMA ஆகும், மேலும் இது server-ல் மிகவும் பயனுள்ள அமைப்பாகும். இயல்பான rollback journal பயன்முறையில், எழுதும் செயல்பாடு (writer) அனைத்து வாசிப்பாளர்களையும் (readers) தடுக்கும். WAL பயன்முறையில், ஒரு writer தரவைச் சேர்க்கும்போது, வாசிப்பாளர்கள் கடைசியாக உறுதிப்படுத்தப்பட்ட (committed) நிலையைத் தொடர்ந்து வாசிக்க முடியும். இதனால், மெதுவான report செயல்பாடு அதற்குப் பின்னால் வரும் web request-ஐத் தடுக்காது.
வரி (row) வந்துள்ளதா எனச் சரிபார்க்கவும்:
sqlite3 /srv/app/app.db "SELECT * FROM orders WHERE customer = 'ana';"உங்களுக்கு 1|ana|2026-07-30T09:14:00Z|4200 கிடைக்கும். தரவுத்தளத்திற்கு அருகில் app.db-wal மற்றும் app.db-shm என மேலும் இரண்டு கோப்புகள் தோன்றியிருக்கும், இவை இரண்டும் அந்தத் தரவுத்தளத்தைச் சேர்ந்தவை. application இயங்கிக்கொண்டிருக்கும்போது app.db-ஐ மட்டும் நகலெடுப்பது முழுமையற்ற (torn) backup-ஐ உருவாக்கும், இது குறித்து கீழே விரிவாகக் கொடுக்கப்பட்டுள்ளது.
SQLite ஒரு நேரத்தில் ஒரு writer-ஐ மட்டுமே அனுமதிக்கும். அந்த வரம்பு ஒரு lock ஆகும், queue அல்ல. எனவே, நீண்ட நேரம் காத்திருக்கும் இரண்டாவது writer, நிரந்தரமாகத் தடுப்படுவதற்குப் பதிலாக database is locked பிழையுடன் தோல்வியடையும். உங்கள் application திறக்கும் ஒவ்வொரு connection-லும் PRAGMA busy_timeout = 5000; மூலம் காத்திருப்பு நேரத்தை அதிகரிக்கவும். ஐந்து வினாடிகள் காத்திருப்பு, சாதாரண web பணிச்சுமையில் இத்தகைய பிழைகள் பெரும்பாலானவற்றை நீக்கிவிடும்.
DuckDB எங்கு சிறந்தது: உங்களிடம் ஏற்கனவே உள்ள கோப்புகளில் பகுப்பாய்வு (analytics)
"எத்தனை", "எவ்வளவு" அல்லது "முதல் பத்து எது" என்று தொடங்கும் கேள்விகளுக்கு, உங்கள் உள்ளீடு CSV அல்லது Parquet கோப்புகளாக இருக்கும்போது DuckDB-ஐத் தேர்ந்தெடுக்கவும். அக்டோபர் 27, 2026 நிலவரப்படி, 2.0.0 (ஒரு LTS release) பதிப்பிலான command line client-ஐ நிறுவவும்:
curl https://install.duckdb.org | shநீங்கள் ஒரு குறிப்பிட்ட பதிப்பைக் குறிப்பிடாதவரை, இந்த script சமீபத்திய stable release-ஐ நிறுவும். உதாரணமாக, முந்தைய release-லேயே இருக்க curl https://install.duckdb.org | DUCKDB_VERSION=1.5.6 sh-ஐப் பயன்படுத்தலாம். இது ~/.duckdb/cli/latest/duckdb-ன் கீழ் binary-ஐ நிறுவி, அதை உங்கள் PATH-ல் சேர்க்கும் வரியை அச்சிடும். அது இயங்குவதை உறுதிப்படுத்தவும்:
~/.duckdb/cli/latest/duckdb :memory: "SELECT version();"வினவுவதற்கு (query) ஒரு யதார்த்தமான கோப்பை உருவாக்கவும். இது ஐந்து மில்லியன் வரிசை ஆர்டர்களை zstd மூலம் சுருக்கி Parquet-ல் எழுதும்:
mkdir -p /srv/data
duckdb :memory: "
COPY (
SELECT i AS id,
'cust_' || (i % 5000) AS customer,
TIMESTAMP '2026-01-01 00:00:00' + INTERVAL (i) MINUTE AS placed_at,
(i * 37) % 20000 AS amount_cents
FROM range(5000000) t(i)
) TO '/srv/data/orders.parquet' (FORMAT parquet, COMPRESSION zstd);"இப்போது பகுப்பாய்வுக் கேள்வியைக் கேட்கவும். shell-ஐத் திறந்து, timer-ஐ ஆன் செய்து, எந்தவொரு import படியும் இன்றி நேரடியாகக் கோப்பை வினவவும்:
.timer on
SELECT customer,
count(*) AS orders,
sum(amount_cents)/100.0 AS revenue
FROM '/srv/data/orders.parquet'
GROUP BY customer
ORDER BY revenue DESC
LIMIT 5;வெளியிடப்பட்ட முடிவை நம்புவதை விட, .timer-லிருந்து உங்கள் சொந்த எண்ணைப் படிக்கவும், ஏனெனில் முடிவு உங்கள் disk மற்றும் core எண்ணிக்கையைப் பொறுத்தது. அதன் வடிவம் மட்டுமே முக்கியமானது. அங்கே CREATE TABLE இல்லை, INSERT இல்லை, எந்தவொரு load படியும் இல்லை: DuckDB Parquet footer-ஐப் படித்து, வினவலுக்குத் தேவையான column chunks எவை என்பதைக் கண்டறிந்து, அவற்றை மட்டுமே படித்தது. ஒரு முழு directory-யும் glob, FROM '/srv/data/orders-*.parquet' மூலம் இதேபோல் செயல்படும், இதுவே ஒரு மாத கால தினசரி ஏற்றுமதிகளை ஒரே வினவலாக மாற்றும் வழியாகும்.
Disk வேகம் இதற்கெல்லாம் அடிப்படையாகும், மேலும் column scan என்பது நீண்ட sequential read ஆகும், எனவே NVMe மற்றும் பழைய SATA storage இடையேயான வேறுபாடு SQLite-ன் சிறிய random reads-ஐ விட இங்கே தெளிவாகத் தெரியும்.
DuckDB மூலம் உங்கள் SQLite database-ஐ வாசித்தல்
DuckDB-ன் sqlite extension மூலம் இந்த இரண்டு engines-ம் இணைகின்றன. Application database-ஐ read-only முறையில் இணைக்கவும், இதன் மூலம் analytics query-கள் நேரடி தரவுகளில் (live state) எந்த மாற்றத்தையும் செய்ய முடியாது:
INSTALL sqlite;
LOAD sqlite;
ATTACH '/srv/app/app.db' AS app (TYPE sqlite, READ_ONLY);
SELECT customer, count(*) AS orders
FROM app.orders
GROUP BY customer
ORDER BY orders DESC;இது query செய்யப்படும் நேரத்தில், தரவுகளை நகல் எடுக்காமல் நேரடியாக SQLite கோப்பிலிருந்து வரிகளை (rows) வாசிக்கிறது. இது வசதியானது, ஆனால் வேகமானது அல்ல; ஏனெனில் வட்டில் உள்ள தரவு இன்னும் row storage வடிவிலேயே உள்ளது, அதை DuckDB ஒவ்வொன்றாக வாசிக்க வேண்டியுள்ளது. இதை ஏற்றுமதி (export) செய்ய மட்டும் பயன்படுத்தவும்; ஒவ்வொரு 30 வினாடிக்கும் reload ஆகும் dashboard-க்கு இதைப் பயன்படுத்த வேண்டாம்:
COPY (SELECT * FROM app.orders)
TO '/srv/data/orders-2026-07.parquet' (FORMAT parquet, COMPRESSION zstd);இந்த ஒரு statement-தான் முழுமையான வழிமுறை. சமீபத்திய நேரடி தரவுகள் SQLite-ல் இருக்கும். திட்டமிடப்பட்ட ஏற்றுமதி (scheduled export), முடிந்த காலப்பகுதிகளை Parquet கோப்புகளாக மாற்றும். பல மாதங்களை உள்ளடக்கிய அனைத்து கேள்விகளுக்கும் DuckDB பதிலளிக்கும், அதே சமயம் application database சிறியதாகவே இருக்கும், இது அதன் write வேகத்தைத் தக்கவைக்கும்.
ஏற்றுமதியை கைமுறையாகச் செய்யாமல், ஒரு கால அட்டவணையின்படி இயக்கவும். இதற்கு systemd service மற்றும் timer ஜோடி பொருத்தமான அளவுடையது: ஒன்று COPY-ஐ இயக்கும் unit, மற்றொன்று அதை ஒவ்வொரு இரவும் இயக்கும் timer.
ஒரே VPS-ல் இரண்டையும் இயக்குதல்
இங்கு எதற்கும் container-ஓ அல்லது port-ஓ தேவையில்லை. இரண்டு என்ஜின்களும் libraries என்பதால், நிறுவல் என்பது ஒரு package மற்றும் file path மட்டுமே. உங்கள் stack-ல் உள்ள மற்றவை ஏற்கனவே Docker Compose on the same VPS-ல் இயங்கினால், ஒரு database service-ஐச் சேர்ப்பதற்குப் பதிலாக, அந்தத் தரவு கோப்பகத்தை (data directory) தேவைப்படும் container-க்குள் mount செய்யவும். ஏனெனில், இதில் சேர்ப்பதற்குத் தனியாக service எதுவும் இல்லை.
இந்த அமைப்பில் சிக்கல்களைத் தவிர்க்க இரண்டு விதிகளைப் பின்பற்றவும்.
ஒவ்வொரு என்ஜினுக்கும் தனித்தனி கோப்பகத்தை ஒதுக்கவும்: application எழுதும் SQLite கோப்பிற்கு /srv/app, analytics வாசிக்கும் Parquet கோப்புகளுக்கு /srv/data. அவை ஒரே கோப்பகத்தைப் பகிர்ந்துகொண்டால், ஒன்றைப் பிரதி எடுக்கும் (snapshot) backup பணி மற்றொன்றுடன் மோதலுக்கு வழிவகுக்கும்.
இரண்டு process-களை ஒரே DuckDB database கோப்பிற்கு read-write முறையில் இணைக்க வேண்டாம். ஒரு DuckDB கோப்பை ஒரு நேரத்தில் ஒரு process மட்டுமே எழுதும் உரிமையுடன் வைத்திருக்க முடியும்; இரண்டாவது process அதைத் திறக்க முயன்றால் தோல்வியடையும். பல process-கள் வாசிப்பதற்கு, அவை ஒவ்வொன்றும் access_mode = 'READ_ONLY'-ஐ அமைத்தால் போதுமானது. SQLite-ல் பல process-கள் ஒரே கோப்பைப் பகிர்வதைப் பழகியவர்களுக்கு இது ஆச்சரியமாக இருக்கலாம். உங்கள் analytics Parquet கோப்புகளை மட்டுமே வாசித்தால், இந்தச் சிக்கல் ஏற்படாது. எனவே, நீடித்திருக்கும் தரவை (durable state) SQLite-ல் வைத்திருப்பது சிறந்தது.
காப்புப்பிரதிகள் (Backups) மாறுபடுகின்றன, அந்த வேறுபாடு சிக்கலை ஏற்படுத்தும்
இயங்கிக்கொண்டிருக்கும் ஒரு SQLite database என்பது மூன்று கோப்புகளைக் கொண்டது. அவற்றை cp மூலம் எழுதும் பணியின் நடுவில் நகலெடுத்தால், திறக்கக்கூடிய ஆனால் தவறான தரவுகளைக் கொண்ட ஒரு கோப்பு கிடைக்கும். எனவே, application தொடர்ந்து தரவுகளை எழுதிக்கொண்டிருக்கும்போதே, சீரான snapshot-ஐ எடுக்கும் அந்த engine-ன் சொந்த backup கட்டளையைப் பயன்படுத்தவும்:
sqlite3 /srv/app/app.db ".backup '/srv/backup/app-$(date -u +%Y%m%dT%H%M%SZ).db'"
sqlite3 /srv/backup/app-20260730T091400Z.db "PRAGMA integrity_check;"integrity_check கட்டளையானது, சரியான நகல் எடுக்கப்பட்டால் ok என்று வெளியிடும். வேறு ஏதேனும் வெளியீடு வந்தால், அந்த snapshot-ஐ நீக்கிவிட்டு மீண்டும் புதியதாக எடுக்கவும்.
Parquet கோப்புகள் எழுதப்பட்ட பிறகு மாறாது, எனவே அவற்றுக்குச் சிறப்பு கையாளுதல் தேவையில்லை: அந்த directory-ஐ அப்படியே காப்புப்பிரதி எடுக்கவும். உங்கள் VPS-லிருந்து restic backups மூலம் இரண்டு பாதைகளையும் server-க்கு வெளியே அனுப்பவும். இப்போது முழு தரவு அடுக்குமே ஒரே backup பணியில் இரண்டு directory-களாக இருக்கும்.
தோல்வி முறைகள் மற்றும் நீங்கள் காணும் துல்லியமான சரங்கள்
உங்கள் application-ன் driver மூலமாகவோ அல்லது sqlite3 shell மூலமாகவோ வரும் SQLite-ன் database is locked, மற்றொரு இணைப்பு உங்கள் timeout அனுமதித்ததை விட நீண்ட நேரம் write lock-ஐ வைத்திருந்தது என்று பொருள். இது தரவுச் சிதைவு (corruption) அல்ல. ஒவ்வொரு இணைப்பிலும் PRAGMA busy_timeout-ஐ அமைக்கவும், பின்னர் பல சிறிய பரிவர்த்தனைகளாக இருக்க வேண்டிய ஒரு நீண்ட பரிவர்த்தனையைத் தேடவும்.
அனுமதி மாற்றத்திற்குப் பிறகு வரும் unable to open database file, அந்த process-ஆல் கோப்பை எழுத முடியும், ஆனால் அதன் directory-ஐ எழுத முடியாது என்று பொதுவாகப் பொருள். SQLite தரவுத்தளத்திற்கு அருகில் app.db-wal மற்றும் app.db-shm ஆகியவற்றை உருவாக்குகிறது, எனவே .db கோப்பு மட்டுமல்லாமல், அந்த directory-யும் எழுதக்கூடியதாக (writable) இருக்க வேண்டும்.
DuckDB-லிருந்து வரும் IO Error: Could not set lock on file, அந்தத் தரவுத்தளத்தை ஏற்கனவே மற்றொரு process எழுதுவதற்காகத் திறந்து வைத்துள்ளது என்று பொருள். மற்ற shell-ஐ மூடவும் அல்லது உங்களுடையதை read only முறையில் திறக்கவும்.
சிறிய VPS-ல் DuckDB-லிருந்து வரும் Out of Memory Error, ஒரு query-க்கு இருந்ததை விட அதிக working memory தேவைப்பட்டது என்று பொருள். DuckDB இயல்பாகவே இடைநிலை முடிவுகளை disk-க்கு மாற்றும் (spill), இதில் :memory: session-ம் அடங்கும், எனவே தரவுத்தளக் கோப்பைத் திறப்பது மட்டும் spill வேலை செய்யக் காரணமாகாது. இது அந்தத் தற்காலிகக் கோப்புகளைத் தரவுத்தளக் கோப்பிற்கு அருகில் உள்ள .tmp directory-ல் எழுதும், அல்லது in-memory session-ஆக இருந்தால், நீங்கள் அதைத் தொடங்கிய இடத்திற்கு அருகில் உள்ள .tmp directory-ல் எழுதும். எனவே, போதுமான disk இடம் உள்ள எழுதக்கூடிய இடத்தில் அதைத் தொடங்கவும் அல்லது SET temp_directory = '/var/tmp/duckdb'; மூலம் வேறு இடத்தைச் சுட்டிக்காட்டவும். முக்கியமான அமைப்பு அதன் வரம்பு ஆகும்: SET memory_limit = '2GB';. இது machine-ன் RAM-ல் 80% ஆகும், எனவே பிற சேவைகள் இயங்கும் ஒரு கணினியில், இந்த வரம்புதான் ஒரு ad hoc query உங்கள் application-ஐ RAM-லிருந்து வெளியேற்றுவதைத் தடுக்கிறது. string_agg() போன்ற சில aggregates-களால் spill செய்ய முடியாது, சில sorting அடிப்படையிலான aggregates-களாலும் முடியாது, எனவே அவற்றை அடிப்படையாகக் கொண்ட ஒரு query இன்னும் memory பற்றாக்குறையை ஏற்படுத்தலாம்.
Parquet-ஐ வினவும்போது வரும் Binder Error: Referenced column "amount" not found, கோப்பின் schema நீங்கள் நினைவில் வைத்திருப்பது அல்ல என்பதை ஏறக்குறைய எப்போதும் குறிக்கிறது. DESCRIBE SELECT * FROM '/srv/data/orders.parquet';-ஐ இயக்கி, உண்மையான column பெயர்களைச் சரிபார்க்கவும்.
நடைமுறையில் எவ்வாறு தேர்வு செய்வது
எழுதுதல் முறை (write pattern) என்னவென்று கேளுங்கள். மின்சாரம் துண்டிக்கப்பட்டாலும் அழியக்கூடாத பல சிறிய எழுதல் செயல்பாடுகள் இருந்தால், SQLite-ஐப் பயன்படுத்தவும். வாசிப்பு முறை (read pattern) என்னவென்று கேளுங்கள். நீண்ட கால வரலாற்றின் மீது முழுமையான ஸ்கேன்கள் (full scans) மற்றும் தொகுப்பு செயல்பாடுகள் (aggregates) தேவைப்பட்டால், DuckDB-ஐப் பயன்படுத்தவும். பெரும்பாலான நிஜ உலக அமைப்புகள் இவ்விரண்டு கேள்விகளுக்கும் ஆம் என்றே பதிலளிக்கும். அத்தகைய சூழலில், ஒரு engine-ஐ மற்றொன்றின் மீது திணிப்பதற்குப் பதிலாக, ஒவ்வொன்றும் சிறப்பாகச் செயல்படும் பகுதியை அதற்கு ஒதுக்குவதே சரியான அணுகுமுறையாகும்.
தவிர்க்க வேண்டிய இடம்பெயர்வு (migration) எதுவென்றால், ஒரு அறிக்கை (report) மெதுவாக இயங்குகிறது என்பதற்காக நேரடி application தரவுகளை DuckDB-க்கு மாற்றுவதுதான். அந்த அறிக்கை மெதுவாக இருந்ததற்குக் காரணம் சேமிப்பக அமைப்பு (storage layout) ஆகும். எனவே, உங்கள் எழுதல் பாதையை (write path) மீண்டும் எழுதுவதற்குப் பதிலாக, தரவுகளை ஏற்றுமதி (export) செய்வதே சரியான தீர்வாகும்.
FAQ
எனது application database-க்கு SQLite-க்கு பதிலாக DuckDB-ஐ பயன்படுத்தலாமா?
அடிக்கடி தரவுகளை எழுதும் (write) பயன்பாடுகளுக்கு இது உகந்ததல்ல. DuckDB முழு database கோப்பின் மீதும் write lock-ஐப் பயன்படுத்துகிறது. ஒரே நேரத்தில் ஒரு process மட்டுமே எழுத முடியும். இது ஒற்றை வரிசை (single-row) பதிவுகளை விட, மொத்தமாக தரவுகளைச் சேர்ப்பதற்கே (bulk changes) வடிவமைக்கப்பட்டுள்ளது. எனவே, transactional தரவுகளை SQLite-ல் வைத்துக்கொண்டு, அறிக்கை (report) தேவைப்படும்போது மட்டும் ATTACH '/srv/app/app.db' AS app (TYPE sqlite, READ_ONLY); மூலம் DuckDB-ஐப் பயன்படுத்தி வாசிக்கவும்.
பகுப்பாய்விற்கு (analytics) SQLite-ஐ விட DuckDB உண்மையில் வேகமானதா?
பெரிய அட்டவணைகளில் தரவுகளைத் தேடுவதற்கும் (scans) தொகுப்பதற்கும் (aggregates) ஆம், இது வேகமானது. இதற்குக் காரணம் அதன் சேமிப்பு முறை (storage layout) ஆகும். ஒரு query-ல் குறிப்பிடப்பட்ட columns-ஐ மட்டுமே DuckDB வாசிக்கும் மற்றும் தரவுகளைத் தொகுதிகளாக (batches) கையாளும். ஆனால், ஒரு குறிப்பிட்ட field-ஐ அடைய SQLite முழு வரிசையையும் கடக்க வேண்டியிருக்கும். primary key மூலம் ஒரு வரிசையை மட்டும் எடுக்கும்போது நிலைமை தலைகீழாகும்; ஏனெனில் SQLite இரண்டு பக்கங்களை (pages) மட்டுமே தொடும், ஆனால் DuckDB ஒவ்வொரு column-ன் சேமிப்பகத்தையும் அணுக வேண்டியிருக்கும்.
VPS-ல் DuckDB-ஐ இயக்க அதிக RAM தேவையா?
இல்லை, ஆனால் அதற்கு ஒரு வரம்பை (limit) நிர்ணயித்து, தரவுகளைத் தற்காலிகமாகச் சேமிக்க இடவசதி அளிப்பது அவசியம். DuckDB இயல்பாகவே இடைநிலை முடிவுகளை (intermediate results) வட்டில் (disk) சேமிக்கும், :memory: session-ல் கூட இது பொருந்தும். இதற்கு அதன் தற்காலிகக் கோப்பகம் (temporary directory) எழுதக்கூடியதாகவும், போதுமான இடவசதி கொண்டதாகவும் இருக்க வேண்டும். பிறகு SET memory_limit = '2GB';-ஐ உங்கள் VPS-ன் வசதிக்கேற்ப அமைக்கவும். இயல்புநிலையான 80% RAM-ல் விட்டால், ஒரு பெரிய GROUP BY, Out of Memory Error-ஐத் தூண்டலாம் அல்லது பிற சேவைகளை RAM-லிருந்து வெளியேற்றலாம்.
எனது SQLite தரவுகளை எப்படி Parquet-க்கு மாற்றுவது?
DuckDB-லிருந்து SQLite கோப்பை இணைத்து (attach), COPY (SELECT * FROM app.orders) TO '/srv/data/orders.parquet' (FORMAT parquet, COMPRESSION zstd); மூலம் query-ஐ நேரடியாக நகலெடுக்கவும். கடந்த மாதத் தரவுகள் போன்ற முடிவடைந்த காலங்களுக்கு இதை ஒரு கால அட்டவணைப்படி (schedule) இயக்கவும். சமீபத்திய தரவுகளை application எழுதும் SQLite-லேயே வைத்திருக்கவும்.
எதை, எப்படி backup எடுப்பது?
இரண்டையும் வெவ்வேறு வழிகளில் backup எடுக்க வேண்டும். SQLite-க்கு cp-க்கு பதிலாக sqlite3 app.db ".backup '/srv/backup/app.db'" மூலம் snapshots எடுக்கவும். ஏனெனில் இயங்கிக்கொண்டிருக்கும் database என்பது ஒரு -wal மற்றும் -shm கோப்பாகவும் இருப்பதால், சாதாரண நகல் (plain copy) சிதைந்துவிட வாய்ப்புள்ளது. Parquet கோப்புகள் எழுதப்பட்ட பிறகு மாறுவதில்லை, எனவே அந்த directory-ஐ நகலெடுப்பதே போதுமானது.