diff --git a/internal/storage/dolt/queries.go b/internal/storage/dolt/queries.go
index 7d8214ee..8acdaae2 100644
--- a/internal/storage/dolt/queries.go
+++ b/internal/storage/dolt/queries.go
@@ -212,8 +212,21 @@ func (s *DoltStore) SearchIssues(ctx context.Context, query string, filter types
 	}
 
 	// nolint:gosec // G201: whereSQL contains column comparisons with ?, limitSQL is a safe integer
+	// Performance fix: SELECT all columns directly instead of id-only + WHERE IN (all_ids)
+	// See: hq-ihwsj - bd list uses inefficient WHERE IN (all_ids) query pattern
 	querySQL := fmt.Sprintf(`
-		SELECT id FROM issues
+		SELECT id, content_hash, title, description, design, acceptance_criteria, notes,
+		       status, priority, issue_type, assignee, estimated_minutes,
+		       created_at, created_by, owner, updated_at, closed_at, external_ref,
+		       compaction_level, compacted_at, compacted_at_commit, original_size, source_repo, close_reason,
+		       deleted_at, deleted_by, delete_reason, original_type,
+		       sender, ephemeral, pinned, is_template, crystallizes,
+		       await_type, await_id, timeout_ns, waiters,
+		       hook_bead, role_bead, agent_state, last_activity, role_type, rig, mol_type,
+		       event_kind, actor, target, payload,
+		       due_at, defer_until,
+		       quality_score, work_type, source_system
+		FROM issues
 		%s
 		ORDER BY priority ASC, created_at DESC
 		%s
@@ -225,7 +238,15 @@ func (s *DoltStore) SearchIssues(ctx context.Context, query string, filter types
 	}
 	defer rows.Close()
 
-	return s.scanIssueIDs(ctx, rows)
+	var issues []*types.Issue
+	for rows.Next() {
+		issue, err := scanIssueRow(rows)
+		if err != nil {
+			return nil, err
+		}
+		issues = append(issues, issue)
+	}
+	return issues, rows.Err()
 }
 
 // GetReadyWork returns issues that are ready to work on (not blocked)
