sql是过程性操作语言
```html 你写一句 SQL 被归为声明式语言,程性操作教科书写了几十年。程性操作声明式的程性操作意思是你说“要什么”,不说“怎么拿”。可实际写 SQL 的人都知道, 我见过一个真实的例子。两张表关联查询,A 表十万行,B 表五千行。同事写的是 存储过程更是把过程性暴露得彻底。你在里面写循环、条件分支、变量赋值、游标遍历,一行一行控制数据怎么流动。这跟写 C 或 Python 没本质区别,只是语法换成了 SQL 的壳。有人觉得存储过程“不 SQL”,其实它才是 SQL 过程性本质的放大镜。你告诉数据库:先查这个,拿到结果赋值给变量,如果变量大于某个值就更新那张表,否则插入日志。每一步都是命令,没有声明。 再想一层。 当然,SQL 确实有声明式的成分。 所以别被“声明式”这个标签骗了。写 SQL 的时候,脑子里得有一台虚拟的机器:数据从哪张表先流出来,经过哪些过滤和连接,最后汇到哪里。你写的每个关键字都是给这台机器下的指令。它不猜你的心思,它只执行你的过程。SELECT * FROM users WHERE id = 1;,数据库返回一行。程性操作这看起来像声明——告诉它你要什么,程性操作它自己想办法。程性操作但把这句话拆开看,程性操作每一步都在规定动作:先定位 users 这张表,程性操作再逐行扫描 id 列,程性操作每读一行做一次等值比较,程性操作命中就放进结果集。程性操作数据库没有“自己想办法”,程性操作它执行的程性操作是你用关键字拼出来的操作序列。这就是程性操作过程性语言的底子。WHERE 子句的写法直接决定走不走索引,JOIN 的顺序影响中间结果集的大小,GROUP BY 放在子查询里还是外层,执行计划能差出两个数量级。如果 SQL 真是纯声明式,这些差异不该存在——数据库应该自动选最优路径。它没有。优化器是个有经验的工匠,不是魔术师,你给的指令越精确,它越省力。SELECT ... FROM A JOIN B ON A.b_id = B.id WHERE B.status = 1;,跑了四十多秒。我改成先把 B 表过滤出来:SELECT ... FROM A JOIN (SELECT id FROM B WHERE status = 1) t ON A.b_id = t.id;,零点三秒。同样的结果集,不同的过程描述。数据库没有“智能”到看穿你的意图,它只是忠实地执行你写的步骤——先扫哪张表、什么时候过滤、怎么连接,全在你手底下。INSERT INTO ... SELECT ... 这个语法本身就带着过程感——先把 SELECT 的结果集算出来,再逐行插进目标表。如果 SQL 是纯声明式,你会写“让目标表拥有源表的数据”,而不是“把源表查出来插进去”。UPDATE ... FROM ... 也是,先做连接,再对匹配行做赋值。这些操作顺序在语法结构里就定死了,你没法打乱。ORDER BY 你只说按哪列排,不说用快排还是归并。但排序算法是数据库实现细节,跟你写的语句无关。而 WHERE 里的条件顺序、JOIN 的嵌套层次、子查询的位置,这些是你写的,数据库不会替你重写。它们直接映射到执行计划里的算子顺序。你写的过程,就是它跑的过程。
- 随机阅读
- 搜索
-
- 友情链接
-