Performing operations on cursors in PostgreSQL - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
When working with cursors in PostgreSQL, it's important to understand how the time to process data grows as the amount of data increases.
We want to know how the number of operations changes when we fetch rows using a cursor.
Analyze the time complexity of the following cursor operations.
DECLARE my_cursor CURSOR FOR
SELECT * FROM large_table;
OPEN my_cursor;
FETCH NEXT FROM my_cursor;
-- repeat FETCH until no more rows
CLOSE my_cursor;
This code declares a cursor to select all rows from a large table, opens it, fetches rows one by one, and then closes it.
- Primary operation: Fetching each row from the cursor one at a time.
- How many times: Once for every row in the result set (n times, where n is the number of rows).
Each fetch operation processes one row, so the total work grows directly with the number of rows.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 fetches |
| 100 | 100 fetches |
| 1000 | 1000 fetches |
Pattern observation: The number of operations increases in a straight line as the number of rows increases.
Time Complexity: O(n)
This means the time to fetch all rows grows directly in proportion to the number of rows you have.
[X] Wrong: "Fetching rows with a cursor is always fast and constant time regardless of data size."
[OK] Correct: Each fetch reads one row, so more rows mean more fetches and more time. The time grows with the number of rows.
Understanding how cursor operations scale helps you explain how database queries behave with large data, a useful skill in real projects and interviews.
"What if we fetched multiple rows at once instead of one by one? How would the time complexity change?"
Practice
Solution
Step 1: Understand what a cursor does
A cursor allows you to handle query results row by row instead of all at once.Step 2: Compare options
Only To process query results one row at a time correctly describes this row-wise processing purpose.Final Answer:
To process query results one row at a time -> Option AQuick Check:
Cursor = row-by-row processing [OK]
- Thinking cursors speed up queries automatically
- Confusing cursors with temporary tables
- Assuming cursors optimize query plans
cur1 for a SELECT query in PostgreSQL?Solution
Step 1: Recall cursor declaration syntax
In PostgreSQL, cursors are declared using DECLARE cursor_name CURSOR FOR query.Step 2: Match syntax with options
DECLARE cur1 CURSOR FOR SELECT * FROM employees; matches the correct DECLARE syntax; others misuse OPEN, FETCH, or CREATE.Final Answer:
DECLARE cur1 CURSOR FOR SELECT * FROM employees; -> Option BQuick Check:
DECLARE cursor FOR query [OK]
- Using OPEN instead of DECLARE to define cursor
- Trying to FETCH during declaration
- Using CREATE CURSOR which is invalid
DECLARE cur CURSOR FOR SELECT id FROM users ORDER BY id; OPEN cur; FETCH NEXT FROM cur; FETCH NEXT FROM cur; CLOSE cur;
What will be the output of the two FETCH commands if the users table has ids 10, 20, 30 in ascending order?
Solution
Step 1: Understand cursor order and FETCH
The cursor selects ids ordered by id: 10, 20, 30. FETCH NEXT returns rows sequentially.Step 2: Trace FETCH commands
First FETCH returns the first row: 10. Second FETCH returns the next row: 20.Final Answer:
First FETCH returns 10, second FETCH returns 20 -> Option AQuick Check:
FETCH NEXT returns rows in order [OK]
- Assuming FETCH skips rows
- Confusing FETCH NEXT with FETCH ALL
- Expecting FETCH to return NULL before end
DECLARE cur CURSOR FOR SELECT name FROM products; OPEN cur; FETCH cur; CLOSE cur; FETCH cur;
What error will occur when running this code?
Solution
Step 1: Analyze cursor lifecycle
Cursor is declared and opened, then FETCH is called once, then cursor is closed.Step 2: Identify error on second FETCH
After CLOSE, cursor is not open, so FETCH causes "cursor is not open" error.Final Answer:
ERROR: cursor "cur" is not open -> Option DQuick Check:
FETCH after CLOSE causes 'not open' error [OK]
- Trying to FETCH after cursor is closed
- Expecting FETCH to reopen cursor automatically
- Confusing 'not open' with 'does not exist' error
orders row by row using a cursor in a PL/pgSQL function. Which sequence of commands correctly opens the cursor, fetches all rows one by one, and closes it after processing?Solution
Step 1: Understand correct cursor usage in PL/pgSQL
Declare cursor, open it, then loop fetching rows until no more rows (EXIT WHEN NOT FOUND), then close cursor.Step 2: Evaluate options
DECLARE cur CURSOR FOR SELECT * FROM orders; OPEN cur; LOOP FETCH cur INTO rec; EXIT WHEN NOT FOUND; -- process rec END LOOP; CLOSE cur; correctly shows DECLARE, OPEN, LOOP with FETCH and EXIT, then CLOSE. Others misuse order or FETCH ALL which fetches all rows at once.Final Answer:
DECLARE cur CURSOR FOR SELECT * FROM orders; OPEN cur; LOOP FETCH cur INTO rec; EXIT WHEN NOT FOUND; -- process rec END LOOP; CLOSE cur; -> Option CQuick Check:
Cursor loop with FETCH and EXIT WHEN NOT FOUND [OK]
- Opening cursor after FETCH
- Using FETCH ALL instead of looping FETCH
- Closing cursor before processing all rows
