✔ PASS Search & Retrieval task_064_Q64_pure_sql_tfidf_calculation Scaled: 1M+ Records Ordered: Yes

TF-IDF (Term Frequency - Inverse Document Frequency) in Pure SQL

Candidate Latency (1M Rows)
173.64 ms
(1.1x faster than golden)
Golden Latency (1M Rows)
195.88 ms
DuckDB in-memory engine
Underlying Data Volume
1,000,000 rows
26.7 MiB across 1 table
Evaluated Model
gemini-3.8-flash-low
Gen Latency: 14.3s
✔ Correctness Verified on 1M+ Records
Candidate SQL output matches ground truth golden query across all multiset rows and numeric tolerances (tol=1e-3). Zero data skew or anti-patterns detected on full dataset scale.

1. Analytical Significance & What It Means

Scenario & Frontier Trap
Business Scenario & Problem

TF-IDF is the foundational algorithm of information retrieval. Calculating it directly in SQL provides deep insight into term uniqueness across a corpus without requiring Python.

⚡ The Frontier Trap (Why LLMs Fail)

Calculating document frequency across millions of documents requires careful window partitioning to avoid Cartesian explosions.

Prompt / User Request Given to Model
TF-IDF is the foundational algorithm of information retrieval. Calculating it directly in SQL provides deep insight into term uniqueness across a corpus without requiring Python.

Execute the required analytical SQL calculation in DuckDB.
Expected output columns: doc_id, term, term_count, tf, idf, tfidf_score.
Results should be ordered as specified.

2. Underlying Tables, Row Counts & Data Volume

1 Tables (1,000,000 rows • 26.7 MiB)

Production-scale fixtures loaded into the isolated DuckDB sandbox with at least 1,000,000 records per table:

📊 doc_words 1,000,000 rows 26.7 MiB Data Volume
doc_id (INTEGER) term (VARCHAR) term_count (INTEGER)
Data Preview (showing sample rows from 1,000,000 total rows):
# doc_id term term_count
1 1 database 10
2 1 columnar 5
3 2 database 8
4 2 relational 7
5 3 columnar 4
6 3 database 6
7 4 columnar 8
8 5 relational 7
9 6 database 7
10 7 columnar 7
11 8 relational 8
12 9 database 5
13 10 columnar 9
14 11 relational 9
15 12 database 6

3. Graphical Query Execution Plan & Cost Bottlenecks

Physical Operator Tree (DuckDB 2.0 Profiler)

Visual flowchart of the physical execution pipeline. Operators with high relative costs (≥ 20% of query runtime or heavy latency) are visually highlighted:

Pipeline Latency Distribution (Total Plan Time: 434.17 ms) Nodes consuming ≥ 20% of query runtime are highlighted with glowing borders
📐 PROJECTION 0.5%
Latency: 2.26 ms
Rows In/Out: 333,334
Data Vol: 15.26 MB
📁 Projections: ['#0', '__internal_...
⏳ ORDER_BY 6.3%
Latency: 27.45 ms
Rows In/Out: 333,334
Data Vol: 14.31 MB
📐 PROJECTION 1.3%
Latency: 5.54 ms
Rows In/Out: 333,334
Data Vol: 14.31 MB
📁 Projections: ['#0', '__internal_...
📐 PROJECTION 6.8%
Latency: 29.65 ms
Rows In/Out: 333,334
Data Vol: 137.33 MB
📁 Projections: ['doc_id', 'term', ...
📐 PROJECTION 6.2%
Latency: 27.00 ms
Rows In/Out: 333,334
Data Vol: 134.79 MB
📁 Projections: ['doc_id', 'term', ...
⚡ HASH_JOIN 7.9%
Latency: 34.14 ms
Rows In/Out: 333,334
Data Vol: 139.87 MB
⚡ HASH_JOIN 4.8%
Latency: 20.71 ms
Rows In/Out: 333,334
Data Vol: 134.79 MB
📊 HASH_GROUP_BY 🔥 27.9% Cost
Latency: 120.98 ms
Rows In/Out: 999,997
Data Vol: 19.07 MB
⚠️ Heavy Execution Bottleneck (27.9% of query runtime)
📐 PROJECTION 0.0%
Latency: 0.13 ms
Rows In/Out: 1,000,000
Data Vol: 7.63 MB
📁 Projections: ['doc_id', 'term_co...
🔍 TABLE_SCAN 0.3%
Latency: 1.29 ms
Rows In/Out: 1,000,000
Data Vol: 7.63 MB
📁 memory.main.doc_words
🔍 TABLE_SCAN 3.2%
Latency: 13.95 ms
Rows In/Out: 333,334
Data Vol: 7.63 MB
📁 memory.main.doc_words
⚙️ CROSS_PRODUCT 0.0%
Latency: 0.03 ms
Rows In/Out: 1
Data Vol: 32 B
📐 PROJECTION 0.0%
Latency: 0.00 ms
Rows In/Out: 1
Data Vol: 24 B
📁 Projections: ['__internal_decomp...
📊 HASH_GROUP_BY 0.9%
Latency: 3.99 ms
Rows In/Out: 1
Data Vol: 24 B
📐 PROJECTION 0.0%
Latency: 0.03 ms
Rows In/Out: 333,334
Data Vol: 5.09 MB
📁 Projections: #0
📐 PROJECTION 0.8%
Latency: 3.51 ms
Rows In/Out: 333,334
Data Vol: 5.09 MB
📁 Projections: __internal_compress...
📐 PROJECTION 0.5%
Latency: 2.28 ms
Rows In/Out: 333,334
Data Vol: 5.09 MB
📁 Projections: __internal_decompre...
📊 HASH_GROUP_BY 10.8%
Latency: 46.87 ms
Rows In/Out: 333,334
Data Vol: 6.36 MB
📐 PROJECTION 0.0%
Latency: 0.08 ms
Rows In/Out: 333,334
Data Vol: 6.36 MB
📁 Projections: ['term', 'doc_id']
📐 PROJECTION 0.7%
Latency: 3.25 ms
Rows In/Out: 333,334
Data Vol: 6.36 MB
📁 Projections: ['__internal_compre...
🔍 TABLE_SCAN 3.7%
Latency: 16.05 ms
Rows In/Out: 333,334
Data Vol: 6.36 MB
📁 memory.main.doc_words
📊 UNGROUPED_AGGREGATE 0.0%
Latency: 0.06 ms
Rows In/Out: 1
Data Vol: 8 B
📊 HASH_GROUP_BY 🔥 17.0% Cost
Latency: 74.02 ms
Rows In/Out: 999,997
Data Vol: 3.81 MB
⚠️ Heavy Execution Bottleneck (17.0% of query runtime)
📐 PROJECTION 0.0%
Latency: 0.10 ms
Rows In/Out: 1,000,000
Data Vol: 3.81 MB
📁 Projections: doc_id
🔍 TABLE_SCAN 0.2%
Latency: 0.81 ms
Rows In/Out: 1,000,000
Data Vol: 3.81 MB
📁 memory.main.doc_words
Operator Cost % Latency Processed Rows Data Volume Details / Table Status
HASH_GROUP_BY 27.9% 120.98 ms 999,997 19.07 MB - 🔥 BOTTLENECK
HASH_GROUP_BY 17.0% 74.02 ms 999,997 3.81 MB - 🔥 BOTTLENECK
HASH_GROUP_BY 10.8% 46.87 ms 333,334 6.36 MB - Normal
HASH_JOIN 7.9% 34.14 ms 333,334 139.87 MB - Normal
PROJECTION 6.8% 29.65 ms 333,334 137.33 MB Projections: ['doc_id', 'term', 'term_count', 't Normal
ORDER_BY 6.3% 27.45 ms 333,334 14.31 MB - Normal
PROJECTION 6.2% 27.00 ms 333,334 134.79 MB Projections: ['doc_id', 'term', 'term_count', '( Normal
HASH_JOIN 4.8% 20.71 ms 333,334 134.79 MB - Normal
TABLE_SCAN 3.7% 16.05 ms 333,334 6.36 MB memory.main.doc_words Normal
TABLE_SCAN 3.2% 13.95 ms 333,334 7.63 MB memory.main.doc_words Normal
PROJECTION 1.3% 5.54 ms 333,334 14.31 MB Projections: ['#0', '__internal_compress_string_ Normal
HASH_GROUP_BY 0.9% 3.99 ms 1 0.00 MB - Normal
PROJECTION 0.8% 3.51 ms 333,334 5.09 MB Projections: __internal_compress_string_uhugeint Normal
PROJECTION 0.7% 3.25 ms 333,334 6.36 MB Projections: ['__internal_compress_string_uhugei Normal
PROJECTION 0.5% 2.28 ms 333,334 5.09 MB Projections: __internal_decompress_string(#0) Normal
PROJECTION 0.5% 2.26 ms 333,334 15.26 MB Projections: ['#0', '__internal_decompress_strin Normal
TABLE_SCAN 0.3% 1.29 ms 1,000,000 7.63 MB memory.main.doc_words Normal
TABLE_SCAN 0.2% 0.81 ms 1,000,000 3.81 MB memory.main.doc_words Normal
PROJECTION 0.0% 0.13 ms 1,000,000 7.63 MB Projections: ['doc_id', 'term_count'] Normal
PROJECTION 0.0% 0.10 ms 1,000,000 3.81 MB Projections: doc_id Normal
PROJECTION 0.0% 0.08 ms 333,334 6.36 MB Projections: ['term', 'doc_id'] Normal
UNGROUPED_AGGREGATE 0.0% 0.06 ms 1 0.00 MB - Normal
CROSS_PRODUCT 0.0% 0.03 ms 1 0.00 MB - Normal
PROJECTION 0.0% 0.03 ms 333,334 5.09 MB Projections: #0 Normal
PROJECTION 0.0% 0.00 ms 1 0.00 MB Projections: ['__internal_decompress_string(#0)' Normal

4. Queries Executed (Candidate vs Golden Ground Truth)

Beautified & Syntax Highlighted
Candidate SQL Executed by gemini-3.8-flash-low (Runtime on 1M Rows: 173.64 ms)
WITH doc_lengths AS
  (SELECT doc_id,
          sum(term_count) AS doc_len
   FROM doc_words
   GROUP BY doc_id),
     corpus_stats AS
  (SELECT count(DISTINCT doc_id) AS total_docs
   FROM doc_words),
     term_docs AS
  (SELECT term,
          count(DISTINCT doc_id) AS docs_with_term
   FROM doc_words
   GROUP BY term)
SELECT w.doc_id,
       w.term,
       w.term_count,
       round(w.term_count * 1.0 / l.doc_len, 4) AS tf,
       round(ln(c.total_docs * 1.0 / td.docs_with_term), 4) AS idf,
       round((w.term_count * 1.0 / l.doc_len) * ln(c.total_docs * 1.0 / td.docs_with_term), 4) AS tfidf_score
FROM doc_words w
JOIN doc_lengths l ON w.doc_id = l.doc_id
JOIN term_docs td ON w.term = td.term
CROSS JOIN corpus_stats c
WHERE w.term = 'columnar'
ORDER BY tfidf_score DESC;
Golden Reference Ground Truth SQL (Runtime on 1M Rows: 195.88 ms)
-- Calculate TF-IDF for term 'columnar' across 3 documents
 -- TF = term_count / total_terms_in_doc, IDF = LN(Total_Docs / Docs_With_Term)
 WITH doc_lengths AS
  (SELECT doc_id,
          sum(term_count) AS doc_len
   FROM doc_words
   GROUP BY doc_id),
      corpus_stats AS
  (SELECT count(DISTINCT doc_id) AS total_docs
   FROM doc_words),
      term_docs AS
  (SELECT term,
          count(DISTINCT doc_id) AS docs_with_term
   FROM doc_words
   GROUP BY term)
SELECT w.doc_id,
       w.term,
       w.term_count,
       round(w.term_count * 1.0 / l.doc_len, 4) AS tf,
       round(ln(c.total_docs * 1.0 / td.docs_with_term), 4) AS idf,
       round((w.term_count * 1.0 / l.doc_len) * ln(c.total_docs * 1.0 / td.docs_with_term), 4) AS tfidf_score
FROM doc_words w
JOIN doc_lengths l ON w.doc_id = l.doc_id
JOIN term_docs td ON w.term = td.term
CROSS JOIN corpus_stats c
WHERE w.term = 'columnar'
ORDER BY tfidf_score DESC;
DuckDB Fixture Setup DDL & Data Population
CREATE TABLE doc_words (doc_id INT, term VARCHAR, term_count INT);


INSERT INTO doc_words
VALUES (1, 'database', 10),
       (1, 'columnar', 5),
       (2, 'database', 8),
       (2, 'relational', 7),
       (3, 'columnar', 4);

5. Query Results & Expected Ground Truth

Tabular Comparison
Actual Candidate Output (333,334 rows × 6 cols)
# doc_id term term_count tf idf tfidf_score
1 245,782 columnar 6 1 1.0986 1.0986
2 245,869 columnar 6 1 1.0986 1.0986
3 245,899 columnar 6 1 1.0986 1.0986
4 245,914 columnar 11 1 1.0986 1.0986
5 245,980 columnar 6 1 1.0986 1.0986
6 246,010 columnar 10 1 1.0986 1.0986
7 246,163 columnar 8 1 1.0986 1.0986
8 246,280 columnar 10 1 1.0986 1.0986
9 246,463 columnar 7 1 1.0986 1.0986
10 246,490 columnar 9 1 1.0986 1.0986
11 246,493 columnar 7 1 1.0986 1.0986
12 246,625 columnar 4 1 1.0986 1.0986
13 246,652 columnar 6 1 1.0986 1.0986
14 246,724 columnar 9 1 1.0986 1.0986
15 246,871 columnar 9 1 1.0986 1.0986
16 246,928 columnar 5 1 1.0986 1.0986
17 247,003 columnar 7 1 1.0986 1.0986
18 247,093 columnar 8 1 1.0986 1.0986
19 247,312 columnar 5 1 1.0986 1.0986
20 247,336 columnar 8 1 1.0986 1.0986
21 247,366 columnar 6 1 1.0986 1.0986
22 247,408 columnar 7 1 1.0986 1.0986
23 247,480 columnar 8 1 1.0986 1.0986
24 247,798 columnar 8 1 1.0986 1.0986
25 247,828 columnar 8 1 1.0986 1.0986
Showing first 25 of 333,334 total rows.
Expected Golden Output (333,334 rows × 6 cols)
# doc_id term term_count tf idf tfidf_score
1 123,016 columnar 5 1 1.0986 1.0986
2 123,031 columnar 3 1 1.0986 1.0986
3 123,064 columnar 7 1 1.0986 1.0986
4 123,127 columnar 2 1 1.0986 1.0986
5 123,136 columnar 6 1 1.0986 1.0986
6 123,196 columnar 7 1 1.0986 1.0986
7 123,235 columnar 6 1 1.0986 1.0986
8 123,379 columnar 5 1 1.0986 1.0986
9 123,397 columnar 5 1 1.0986 1.0986
10 123,475 columnar 8 1 1.0986 1.0986
11 123,478 columnar 1 1 1.0986 1.0986
12 123,628 columnar 8 1 1.0986 1.0986
13 123,631 columnar 7 1 1.0986 1.0986
14 123,907 columnar 3 1 1.0986 1.0986
15 123,931 columnar 3 1 1.0986 1.0986
16 124,021 columnar 11 1 1.0986 1.0986
17 124,045 columnar 4 1 1.0986 1.0986
18 124,069 columnar 5 1 1.0986 1.0986
19 124,162 columnar 8 1 1.0986 1.0986
20 124,174 columnar 10 1 1.0986 1.0986
21 124,405 columnar 5 1 1.0986 1.0986
22 124,489 columnar 9 1 1.0986 1.0986
23 124,606 columnar 6 1 1.0986 1.0986
24 124,663 columnar 5 1 1.0986 1.0986
25 124,747 columnar 6 1 1.0986 1.0986
Showing first 25 of 333,334 total rows.
← Prev: High-Precision Boolean Se... ⊞ Back to Benchmark Dashboard Next: Discounted Cumulative Gai... →