今日的科技圈焦點集中在 AI 的實際落地應用與治理爭議。從高效能的本地語音工具,到 AI 程式代理人的沙盒環境,甚至是對 OpenAI 領導權力的深度反思,這一切都顯示我們正處於從「實驗室 AI」轉向「工程化 AI」的關鍵過渡期。對於開發者與技術決策者而言,理解這些技術邊界與信任架構,將是未來幾年的核心競爭力。✨
今日的科技圈展現了兩個極端的碰撞:一方面是 AI 技術正以前所未有的速度向「邊緣裝置」滲透,從 iPhone 到 M3 晶片的 Mac 都能運行高效能模型;另一方面,開發者社群開始重新審視軟體架構的效率,無論是批評微軟長達數十年的介面策略迷失,還是嘗試用更輕量級的技術重新建構開發工具。這是一個技術回歸效能與透明度的時代,值得每位技術人深思。
🤖 AI / 機器學習
Gemma 4 正式登陸 iPhone 📱
Google 最新的開放模型 Gemma 4 現在已可透過「Google AI Edge Gallery」在 iOS 平台上運行。這象徵著行動端邊緣運算的重大突破,使用者無需依賴雲端伺服器即可在 iPhone 上體驗高效能的語言模型處理。這不僅提升了隱私性,更大幅降低了延遲,標誌著個人 AI 助手邁向新里程碑。
這篇文章深刻分析了微軟在 Windows 圖形使用者介面(GUI)發展上的混亂。作者指出自從經典教科書作者 Charles Petzold 的時代後,微軟不斷在 Win32, WPF, UWP, WinUI 等技術間搖擺。這導致了現代 Windows 介面破碎且缺乏一致性的開發體驗,引發了資深開發者的強烈共鳴。
16:35:53 offloaded 42/43 layers to GPU(模型開始載入)
16:38:53 llm server not responding
16:38:54 llm server loading model
16:39:02 llm server not responding
16:39:03 llm server loading model
...(反覆了將近 6 分鐘)
16:42:28 llama runner started in 410.58 seconds(終於啟動)
17:04:49 -- Boot --(機器直接重開機)
今日的科技圈展現了從底層硬體架構、作業系統標準化到 AI 頂層思維的全面交織。我們不僅看到了 Andrej Karpathy 對 LLM 未來的深度思考,也見證了 Valve 如何透過資本力量重塑 Linux 生態,以及微軟在品牌命名上的策略迷思。對於開發者與科技愛好者來說,理解這些趨勢將有助於掌握軟硬體整合的新賽道。
🤖 AI / 機器學習
LLM Wiki – Andrej Karpathy 的「靈感筆記」
前 Tesla AI 負責人 Andrej Karpathy 分享了他關於大語言模型(LLM)的個人維基草稿。這份文件被稱為「想法檔案」,記錄了他對 LLM 作為一種新型作業系統、模型評估機制以及未來發展方向的深刻洞見。這對於想要理解頂尖 AI 專家如何思考模型架構與應用的讀者來說,是極具價值的參考資料。
評論指出,當社群還在爭論 Linux 初始化系統時,Valve 已經投入巨資支持 Flatpak 架構。透過 Steam Deck 的成功,Valve 實際上正在推動 Linux 桌面應用程式的標準化,解決了長期以來 Linux 套件零碎化的問題。這標誌著商業力量介入後,Linux 生態可能迎來真正的「大統一」。
用同款 gemma4:e4b,在 Mini PC 和 MacBook Air M3 上各跑一輪,看看換硬體能得到什麼。
速度差 6.7 倍,不只是快慢的問題
Mini PC 平均 1.45 tok/s,Mac 平均 9.75 tok/s。這個差距背後的原因是架構:Mini PC 用 x86 CPU 做矩陣運算,效率遠低於 Apple Silicon 的 Neural Engine + 統一記憶體架構。M3 的統一記憶體讓 CPU 和 GPU 共享同一塊 24GB,模型權重可以直接放在 GPU 能讀取的記憶體,不需要搬移。
記憶體夠,輸出才完整
這是硬體差距最直接的體現:Q2 要求生成一個能解析多種日期格式的 Python 函式,Mini PC 在 600 token 限制下就截斷了(回答還在中途),而 Mac 無限制跑出 2218 tokens 的完整函式。
Q4 要求生成帶有 CTE 和 Window Function 的複雜 SQL,Mini PC 截斷,Mac 輸出完整 1043 tokens 含說明。這不是模型能力的差異,是記憶體和 KV Cache 空間的差異。
WITH RecentSpending AS (
SELECT o.customer_id, SUM(o.amount) AS total_spending
FROM orders o
WHERE o.created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
GROUP BY o.customer_id
),
RankedCustomers AS (
SELECT c.name, c.city, rs.total_spending,
RANK() OVER (PARTITION BY c.city ORDER BY rs.total_spending DESC) as city_rank
FROM RecentSpending rs
JOIN customers c ON rs.customer_id = c.id
)
SELECT city, name, total_spending
FROM RankedCustomers
WHERE city_rank <= 3
ORDER BY city, city_rank;
Thinking 版本(1413 tokens)在 SQL 後面額外附上了欄位說明對照表、RANK vs DENSE_RANK 的差異說明、以及在資料量大時建議加索引的備注。這種「自動補充說明」的行為,在程式碼審查或教學場景特別有用。
原則是:不需要記憶 codebase、不需要複雜推理的任務,都可以先試 Mac。速度快、免費、資料不出門。遇到 Mac 答不好的,再升到 Claude。
進階應用二:Mini PC + Mac 混合架構,讓 Agent Team 更有效率
角色定義(固定,不隨任務改變)
Mini PC → 純指揮中心:跑 Claude Code、管理 Agent Team、處理串接邏輯
不跑任何本地模型,資源用在穩定性和協調上
Mac → 推理後端:跑 Ollama + gemma4:e4b
只負責生成,不做決策
Claude API → 審查 + 架構:程式碼審查、複雜邏輯、跨檔案推理
Mini PC 透過網路呼叫,不在本地
規則:Mac 不在線 → fallback 給 Claude API,不是 Mini PC 自己跑
當你用 Claude Code 的 Agent Team 跑自動化程式開發時,會面對一個現實問題:Claude API 的費用隨 token 用量線性增長,而很多任務其實不需要 Claude 的完整推理能力——DTO 生成、CRUD 樣板、SQL migration 這類結構性重複工作,本地的 gemma4:e4b 就能處理。
解法是把 Mac 當成 Agent Team 的「草稿後端」:Claude Agent 負責架構決策和程式碼審查,Mac gemma4 負責產生第一版草稿,再由 Claude 驗證整合。
架構分工
任務類型
交給誰
原因
DTO / model class
Mac gemma4
結構固定,重複性高
CRUD endpoints 樣板
Mac gemma4
Pattern 固定,不需要推理
SQL migration
Mac gemma4
有範本可循
Unit test 骨架
Mac gemma4
快速產出結構,Claude 填邏輯
複雜業務邏輯
Claude sonnet
需要跨檔案理解,Mac 沒有 context
安全相關程式碼
Claude sonnet/opus
不可靠的輸出風險太高
架構決策 / Code Review
Claude opus
需要深度推理與判斷
前置設定:讓 Mac 的 Ollama 對區網開放
Ollama 預設只監聽本機。在 Mac 上把它開放給區網,Mini PC 才能連進來:
# Mac 上執行(停掉 Ollama app 後)
OLLAMA_HOST=0.0.0.0 ollama serve
# 從 Mini PC 驗證是否連得到(換成 Mac 的區網 IP)
curl http://192.168.1.xxx:11434/api/tags
不想暴露 port 的話,用 SSH Tunnel:Mini PC 上執行 ssh -L 11435:localhost:11434 [email protected] -N,之後打 localhost:11435 就等於打 Mac 的 Ollama。
#!/usr/bin/env python3
"""
mac_draft.py — Call Mac's local gemma4 for code draft generation.
Usage:
python3 mac_draft.py "write a SQLAlchemy User model with id, name, email"
python3 mac_draft.py --task "CRUD for User" --context "FastAPI, SQLAlchemy async"
Exit codes:
0 = success, draft printed to stdout
1 = Mac unreachable → fallback: implement with Claude directly
2 = model error
"""
import json, sys, urllib.request, urllib.error, argparse
MAC_HOST = "http://192.168.1.xxx:11434" # 改成 Mac 的實際 IP
MODEL = "gemma4:e4b"
TIMEOUT = 600
SYSTEM_PROMPT = """You are a code generation assistant. Output ONLY code —
no explanations, no markdown fences, no comments unless essential.
The output will be reviewed and integrated by another agent."""
def check_reachable():
try:
with urllib.request.urlopen(f"{MAC_HOST}/api/tags", timeout=5):
return True
except Exception:
return False
def generate(task, context=""):
prompt = f"Context: {context}\n\nTask: {task}" if context else task
payload = {
"model": MODEL,
"messages": [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": prompt},
],
"stream": False, "think": False,
"options": {"num_ctx": 4096, "num_predict": -1},
}
data = json.dumps(payload).encode()
req = urllib.request.Request(
f"{MAC_HOST}/api/chat", data=data,
headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(req, timeout=TIMEOUT) as r:
return json.loads(r.read())["message"]["content"]
parser = argparse.ArgumentParser()
parser.add_argument("task", nargs="?")
parser.add_argument("--task", dest="task_flag")
parser.add_argument("--context", default="")
args = parser.parse_args()
task = args.task or args.task_flag
if not task:
print("ERROR: no task provided", file=sys.stderr); sys.exit(1)
if not check_reachable():
print(f"MAC_UNREACHABLE: {MAC_HOST}. Fallback: implement with Claude.",
file=sys.stderr); sys.exit(1)
try:
print(generate(task, args.context))
except Exception as e:
print(f"ERROR: {e}", file=sys.stderr); sys.exit(2)
Agent 的實際使用流程
# Agent (sonnet) 在 Bash tool 中這樣呼叫:
# 1. 請 Mac 出草稿
draft=$(python3 ~/llm-benchmark/scripts/mac_draft.py \
--task "generate SQLAlchemy User model" \
--context "PostgreSQL, async, Pydantic v2")
# 2. 檢查是否成功
if [ $? -ne 0 ]; then
echo "Mac unavailable, implementing directly"
# Claude 自己寫
fi
# 3. 草稿給 Claude 審查後整合進 codebase
echo "$draft" # Claude 讀到這裡,決定是否採用、修改哪裡
告訴 Agents 這條規則:寫入 AGENTS.md
Claude Code 的 Agent Team 每個 subagent 啟動時沒有對話歷史。規則要寫進 AGENTS.md,agent 才會在每次任務開始時讀到它。在專案的 AGENTS.md 加上這個區塊:
## Mac Draft Resource (Local LLM Offload)
Mac (gemma4:e4b) is available as a fast code draft generator.
Tool: python3 ~/llm-benchmark/scripts/mac_draft.py
Use Mac draft BEFORE writing code yourself for:
- DTO / model class boilerplate ✅
- CRUD endpoints (standard pattern) ✅
- SQL migration scripts ✅
- Unit test scaffolding ✅
Do NOT use Mac draft for:
- Complex business logic ❌ (no codebase context)
- Security-sensitive code ❌ (unreliable)
- Cross-file refactoring ❌ (no context)
- Architecture decisions ❌ (use opus)
Workflow:
1. Call mac_draft.py with task description
2. exit code 1 (MAC_UNREACHABLE) → implement with Claude directly
3. Review draft: check patterns, imports, logic, security
4. Integrate into codebase
Mac generates the shape. Claude ensures it fits.
這樣每個 subagent 都會知道「遇到樣板類任務先叫 Mac 出草稿」,不需要每次重新交代規則。
結論與推薦
本次測試跨越三個維度,每層都有明確的答案:
Mini PC + Mac 混合架構的定位
Mini PC 的角色是指揮中心,不是推理引擎。它跑 Claude Code、管理 Agent Team、處理串接邏輯,資源用在穩定性和協調上。推理工作全部交給 Mac 的 gemma4:e4b。
日常問答 / 摘要:Mini PC 發問 → Mac gemma4 回答,免費、快速、資料不出門
草稿程式碼:Agent 呼叫 mac_draft.py → Mac 出草稿 → Claude 審查整合
複雜推理 / 架構決策:直接用 Claude API,不走 Mac
Mac 不在線:fallback 給 Claude API,Mini PC 本身不需要跑任何模型
如果你的情境是 Mini PC 獨立運作(沒有 Mac),模型選擇建議:gemma4:e4b 速度最快(1.45 tok/s)、qwen3:14b 完成度最高(7/7 全答)、qwen3:4b 最省記憶體。但這個架構的速度上限就是 CPU 推論,不如 Mac 的 Apple Silicon。
真正的瓶頸不是模型大小,而是硬體架構。同款模型在 Apple Silicon 上跑出的效果,在 x86 CPU 上根本發揮不出來。如果你認真考慮本地 LLM,MacBook Air M3 是目前性價比最高的入門選擇;Mini PC 路線則需要搭配 NVIDIA GPU(VRAM ≥ 8GB)才能真正發揮。
今日科技圈的焦點集中在 AI 生態系統的治理衝突與底層技術的持續演進。從 Anthropic 對第三方工具的政策收緊,到全球儲備資產的歷史性轉移,這些動態不僅影響開發者的工具選擇,更預示了未來幾年商業競爭與技術標準的新賽局。身為開發者或決策者,理解這些變革背後的邏輯至關重要。
🤖 AI / 機器學習
Anthropic 不再允許 Claude Code 訂閱用戶使用 OpenClaw
Anthropic 最近更新了其政策,明確禁止 Claude Code 的訂閱用戶配合使用第三方開源工具 OpenClaw。這項舉動引發了社群對於 AI 平台「圍牆花園」政策的激烈討論。許多開發者認為這限制了工具的靈活性與自動化潛力,但也反映了原廠對於 API 使用安全與商業利益的保護。這標誌著 AI 供應商開始從早期的開放探索轉向更嚴格的生態控制。
Anthropic 發表了一項深入的研究,探討 AI 模型內部是如何表徵與處理「情感」概念的。研究顯示,模型內部存在特定的神經元激活模式,用以識別與模擬人類的情感狀態,這並非單純的文字模仿,而是具有一定的功能性結構。這項研究有助於我們理解 LLM 的可解釋性,並在未來開發出更具同理心或可控的 AI 系統。這對於致力於 AI 安全與人機互動的專家來說是極具價值的參考。
Podroid 專案展示了在 Android 裝置上運行完整 Linux 容器的可能性,且過程不需要最高權限(Root)。這意味著行動裝置可以化身為輕量級的開發服務器或測試環境,極大地擴展了 Android 裝置的生產力邊界。該專案利用了 Linux 內核的 Namespace 等技術,對於對行動開發或邊緣運算感興趣的工程師來說,這是一個非常有趣的嘗試。這也證明了現代行動作業系統與傳統 Linux 環境的融合度正在提升。
這篇文章深入淺出地講解了如何將一台普通的多網口 Linux 主機配置成高效的路由器或交換機。作者詳細列出了包括開啟 IP 轉發、配置 NAT 以及優化內核參數等七項關鍵步驟。這不僅是一篇實用的教學,更是一堂深刻的網絡底層原理課,適合想要提升網絡調優技能的 DevOps 工程師。了解這些變更,能讓你更精確地掌握封包在系統內部的流轉邏輯。
近期被廣泛討論的開源 AI 工具 OpenClaw 被揭露存在嚴重的權限提升漏洞。該漏洞允許攻擊者在特定條件下獲得系統的高級權限,對於將此工具整合入生產環境的企業來說,具有極高的安全風險。這再次提醒我們,在使用新興的開源 AI 封裝工具時,必須進行徹底的安全審計。隨著 AI 工具的普及,針對這類「連接器」的攻擊行為也正在急劇增加。
NASA 的阿提米絲二號(Artemis II)任務傳回了令人嘆為觀止的地球全景圖像,這為人類重返月球的計畫增添了更多信心。這張照片不僅展現了攝影技術在太空極端環境下的進步,也喚起了全球對太空探索的熱情。在繁瑣的技術開發與商業競爭之餘,這類來自太空的視覺震撼,提醒了我們科技發展的最原始初衷:探索未知的疆域。這對航太科技與光學儀器開發者來說是極大的激勵。
// Producer-Consumer pattern with BlockingCollection
var queue = new BlockingCollection<WorkItem>(boundedCapacity: 100);
// Producer thread
Task.Run(() =>
{
foreach (var item in GetWorkItems())
{
// Blocks if queue is full (back-pressure!)
queue.Add(item);
Console.WriteLine($"Produced: {item.Id}");
}
queue.CompleteAdding(); // Signal no more items
});
// Consumer thread
Task.Run(() =>
{
// Blocks automatically when queue is empty
// Exits when CompleteAdding() is called and queue is drained
foreach (var item in queue.GetConsumingEnumerable())
{
ProcessItem(item);
Console.WriteLine($"Consumed: {item.Id}");
}
});
這篇文章是我從 DBA 到全端架構師這幾年,在 SQL Server 效能優化上踩過的坑的總整理。不是教科書式的理論,而是每一條都是我實際測試、實際踩雷後的血淚經驗。如果你正在處理 SQL Server 效能優化的問題——DELETE 後空間沒釋放、查詢莫名其妙變慢、鎖定機制搞不清楚——這篇應該能幫你少走不少冤枉路。
TL;DR 重點摘要
DELETE 不會釋放磁碟空間,只是標記刪除。要真正回收空間,必須用 TRUNCATE 或 ALTER INDEX REBUILD。
NOT IN 是效能炸彈,改用 NOT EXISTS 可以讓查詢快數十倍,尤其在子查詢結果集大的時候。
在 Azure SQL Database 上,大量 DELETE 後看到儲存空間快滿了——這是假警報。空間根本沒被釋放。DELETE ... WITH (TABLOCK) 效果有限,必須搭配 TRUNCATE 或 ALTER INDEX ALL ON [TableName] REBUILD 才能真正回收。
-- Problem: Without TABLOCKX, T2 can read T1's uncommitted changes
-- Session 1
BEGIN TRAN T1;
UPDATE Orders SET Amount = 999 WHERE OrderID = 1;
-- (not committed yet)
-- Session 2 (runs concurrently, sees Amount = 999 → Dirty Read!)
SELECT Amount FROM Orders WHERE OrderID = 1;
-- Solution: Use TABLOCKX for exclusive access
BEGIN TRAN T1;
SELECT * FROM Orders WITH (TABLOCKX) WHERE OrderID = 1;
-- Now T2 is BLOCKED until T1 commits or rolls back
UPDATE Orders SET Amount = 999 WHERE OrderID = 1;
COMMIT TRAN T1;
否定查詢(NOT EXISTS vs NOT IN):NOT EXISTS 遠遠快於 NOT IN,差距可達數十倍。
-- NOT IN: Slow — performs O(n*m) comparison, NULL handling issues
SELECT * FROM Products
WHERE ProductID NOT IN (
SELECT ProductID FROM OrderDetails
);
-- NOT EXISTS: Fast — uses semi-join, stops at first match
SELECT * FROM Products p
WHERE NOT EXISTS (
SELECT 1 FROM OrderDetails od
WHERE od.ProductID = p.ProductID
);
-- Additional trap: if OrderDetails.ProductID contains ANY NULL value,
-- NOT IN returns ZERO rows! NOT EXISTS handles NULL correctly.
NOT IN 之所以慢,是因為它必須對子查詢的每一筆結果做比對,而且還要處理 NULL 的三值邏輯。NOT EXISTS 則是用半連接(Semi-Join)策略,找到第一筆匹配就停止。
排序與 TOP 的隱藏陷阱
加上 TOP 之後,SQL Server 的排序演算法會完全改變。沒有 TOP 時用完整排序(Full Sort),有 TOP 時用 Top-N Sort,記憶體需求和執行路徑完全不同。
SQL 執行順序(必背)
很多查詢優化的問題,根源是不理解 SQL 的實際執行順序:
FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → TOP/OFFSET
注意 SELECT 在 WHERE 之後,所以你不能在 WHERE 中使用 SELECT 裡定義的別名。而 ORDER BY 在 SELECT 之後,所以可以用別名排序。理解這個順序,很多「為什麼這樣寫不行」的問題都迎刃而解。
另外,索引不只消除全表掃描,還能跳過排序階段。如果 ORDER BY 的欄位剛好有索引,SQL Server 可以直接按索引順序讀取,省掉排序的 CPU 和記憶體開銷。
4. 全文檢索 — 比 LIKE ‘%keyword%’ 快一百倍
如果你的應用有「搜尋文章內容」的需求,還在用 LIKE '%keyword%',那你的查詢基本上每次都是全表掃描。全文檢索(Full-Text Search)透過反向索引(Inverted Index)來加速文字搜尋,效能差距是數量級的。
建立全文檢索的前提與步驟
前提:目標表必須有主鍵(Primary Key)。因為反向索引需要唯一識別碼來對應每筆資料。
-- Step 1: Enable full-text search on the database (if not already)
-- (SQL Server installs Full-Text Search as a feature)
-- Step 2: Create a full-text catalog
CREATE FULLTEXT CATALOG ftCatalog AS DEFAULT;
-- Step 3: Create a full-text index on the table
-- The table MUST have a primary key
CREATE FULLTEXT INDEX ON Articles (
Title LANGUAGE 1028, -- 1028 = Traditional Chinese
Content LANGUAGE 1028
)
KEY INDEX PK_Articles -- Must reference the PK
ON ftCatalog
WITH CHANGE_TRACKING AUTO; -- Auto-update when data changes
-- Step 4: Query using CONTAINS or FREETEXT
SELECT * FROM Articles
WHERE CONTAINS(Content, N'效能優化');
-- Compare with LIKE (full table scan every time)
SELECT * FROM Articles
WHERE Content LIKE N'%效能優化%';
SQL Server Profiler 在生產環境不一定能用(效能開銷太大,或者根本沒權限)。這時候 DMV(Dynamic Management Views)就是你的救星。
追蹤特定時間範圍的查詢
-- Find top queries by CPU time within a time range
SELECT TOP 20
qs.last_execution_time,
qs.execution_count,
qs.total_worker_time / 1000 AS total_cpu_ms,
qs.total_elapsed_time / 1000 AS total_elapsed_ms,
qs.total_logical_reads,
SUBSTRING(st.text,
(qs.statement_start_offset / 2) + 1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(st.text)
ELSE qs.statement_end_offset
END - qs.statement_start_offset) / 2) + 1
) AS query_text
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
WHERE qs.last_execution_time >= '2026-04-04 09:00:00'
AND qs.last_execution_time <= '2026-04-04 18:00:00'
ORDER BY qs.total_worker_time DESC;
查看當前執行中的程序
-- Quick check: who's running what right now?
EXEC sp_who2;
-- Or with more detail via DMV
SELECT
r.session_id,
r.status,
r.command,
r.wait_type,
r.wait_time,
t.text AS query_text,
r.cpu_time,
r.reads,
r.writes
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.session_id > 50; -- Exclude system sessions
全庫儲存空間盤點
-- Iterate all user tables and check space usage
CREATE TABLE #SpaceUsed (
TableName NVARCHAR(128),
Rows NVARCHAR(20),
Reserved NVARCHAR(20),
Data NVARCHAR(20),
IndexSize NVARCHAR(20),
Unused NVARCHAR(20)
);
DECLARE @tbl NVARCHAR(128);
DECLARE tbl_cursor CURSOR FOR
SELECT TABLE_SCHEMA + '.' + TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE';
OPEN tbl_cursor;
FETCH NEXT FROM tbl_cursor INTO @tbl;
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO #SpaceUsed
EXEC sp_spaceused @tbl;
FETCH NEXT FROM tbl_cursor INTO @tbl;
END
CLOSE tbl_cursor;
DEALLOCATE tbl_cursor;
SELECT * FROM #SpaceUsed ORDER BY CAST(REPLACE(Reserved, ' KB', '') AS BIGINT) DESC;
DROP TABLE #SpaceUsed;
-- Table variable: optimizer always estimates 1 row
DECLARE @small TABLE (ID INT, Name NVARCHAR(50));
INSERT INTO @small SELECT TOP 10 ID, Name FROM Products;
-- Local temp table: has statistics, better for large datasets
CREATE TABLE #bigtemp (ID INT, Name NVARCHAR(50));
INSERT INTO #bigtemp SELECT ID, Name FROM Products;
CREATE INDEX IX_bigtemp_ID ON #bigtemp(ID); -- Can add indexes
-- Global temp table: visible to all sessions
CREATE TABLE ##shared (ID INT, Name NVARCHAR(50));
-- Other sessions can SELECT from ##shared