SQL查询如何工作?
它是如何编译的?
首先编译from
子句以查看表是否存在?
它是如何从数据库中实际检索数据的?
表格存储在数据库中的方式和格式是什么?
我正在使用phpmyadmin,有什么方法可以查看存储数据的文件吗? 我正在使用MySQL
答案 0 :(得分:13)
嗯...
顺便说一句,查询分析器是您看到巨大差异的地方。不确定MySQL - SQL Server(微软)的亮点在于它没有最好的(但其中一个好的),但它确实有很好的可视化工具来显示查询计划,比较分析器的估计值真正的需求(如果他们有太多不同的表统计信息可能会关闭,所以分析器认为一个大表很小)。他们在视觉上表现得非常好。
DB2在一段时间内有一个很好的优化器,测量 - 我已经说过 - 盘速度将其纳入其估计值。 Oracle长期以来“从左到右”(没有真正的分析),并采用了用户提供的查询提示(废话方法)。我认为MySQL在开始时也非常原始 - 不确定它现在在哪里。
数据库中的表格格式等 - 这是你不应该关心的事情。这是记录的(显然,特别是对于开源数据库),但为什么要关心?我已经做了大约15年左右的SQL工作,从未有过这样的需求。这包括在某些领域做相当高端的工作。除非您尝试构建数据库文件修复工具....否则没有任何意义。
答案 1 :(得分:6)
这是一个很好的问题,但在这里无法完全解答。
您可以阅读书籍Understanding MySQL Internals
,它可以为您提供大部分问题的答案。
答案 2 :(得分:3)
您的问题有胆量。
SQL语句子句的执行顺序-
从->位置->分组依据->拥有->选择->排序依据
我的答案特定于Oracle数据库,该数据库提供了有关您的查询的教程。好吧,当SQL数据库引擎处理任何SQL查询/语句时,它首先开始解析,并在解析过程中执行三个检查语法,语义和< strong>共享池。要知道这些检查如何工作?请点击下面的链接。
查询解析一旦完成,就会触发执行计划。但是,嘿,数据库引擎!你足够聪明。您确实检查此SQL查询是否已经解析( Soft Parse ),如果是,则直接跳转执行计划,否则就深入研究并优化查询( Hard Parse >)。在执行硬解析时,您还使用了名为行源生成的软件,该软件提供了从优化程序接收到的迭代执行计划。足够!请参见下面的SQL查询处理阶段。
注意-在执行计划之前,它还会对变量的值执行 Bind 操作,并在执行查询后执行 Fetch 以获取记录,最后存储到结果集中。简而言之,顺序是-
PASRE-> BIND-> EXECUTE-> FETCH
有关详细信息,this tutorial在等您。 这可能对某人有帮助。
答案 3 :(得分:1)
如果您的目标产品是SQL Server,那么this article是一个很好的起点。
答案 4 :(得分:1)
sql执行顺序:
FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> DISTINCT -> ORDER BY -> LIMIT .
SQL Query 主要工作在三个阶段。
1) 行过滤 - 阶段 1: 行过滤 - 阶段 1 由 FROM、WHERE、GROUP BY、HAVING 子句完成。
2) 列过滤:列由 SELECT 子句过滤。
3) 行过滤 - 阶段 2: 行过滤 - 阶段 2 由 DISTINCT 、 ORDER BY 、 LIMIT 子句完成。
在这里我会用一个例子来解释。假设我们有一个学生表,如下所示:
id_ | name_ | 标记 | 部分 |
---|---|---|---|
1 | 朱莉娅 | 88 | A |
2 | 萨曼莎 | 68 | B |
3 | 玛丽亚 | 10 | C |
4 | 猩红色 | 78 | A |
5 | 阿什利 | 63 | B |
6 | 阿比尔 | 95 | D |
7 | 简 | 81 | A |
8 | 贾希德 | 25 | C |
9 | 索赫尔 | 90 | D |
10 | 拉希姆 | 80 | A |
11 | 卡里姆 | 81 | B |
12 | 阿卜杜拉 | 92 | D |
现在我们运行下面的sql查询:
select section_,sum(marks) from students where id_<10 GROUP BY section_ having sum(marks)>100 order by section_ LIMIT 2;
查询的输出是:
section_ | 总和 |
---|---|
A | 247 |
B | 131 |
但是我们是如何得到这个输出的?
我已经逐步解释了查询。请阅读以下内容:
因此 from 子句首先起作用,因此 from students where id_<10
查询将消除 id_ 大于或等于 10 的行。因此,执行 from students where id_<10
后保留以下行。
id_ | name_ | 标记 | 部分 |
---|---|---|---|
1 | 朱莉娅 | 88 | A |
2 | 萨曼莎 | 68 | B |
3 | 玛丽亚 | 10 | C |
4 | 猩红色 | 78 | A |
5 | 阿什利 | 63 | B |
6 | 阿比尔 | 95 | D |
7 | 简 | 81 | A |
8 | 贾希德 | 25 | C |
9 | 索赫尔 | 90 | D |
现在 GROUP BY 子句会来,这就是为什么在执行 GROUP BY section_
行后会像下面这样创建组:
id_ | name_ | 标记 | 部分 |
---|---|---|---|
9 | 索赫尔 | 90 | D |
6 | 阿比尔 | 95 | D |
1 | 朱莉娅 | 88 | A |
4 | 猩红色 | 78 | A |
7 | 简 | 81 | A |
2 | 萨曼莎 | 68 | B |
5 | 阿什利 | 63 | B |
3 | 玛丽亚 | 10 | C |
8 | 贾希德 | 25 | C |
having sum(marks)>100
将消除组。 D组的sum(marks)为185,A组的sum(marks)为247,B组的sum(marks)为131,C组的sum(marks)为35。所以我们可以看到 C 组的总和不大于 100 。所以C组将被淘汰。所以表格看起来像这样:
id_ | name_ | 标记 | 部分 |
---|---|---|---|
9 | 索赫尔 | 90 | D |
6 | 阿比尔 | 95 | D |
1 | 朱莉娅 | 88 | A |
4 | 猩红色 | 78 | A |
7 | 简 | 81 | A |
2 | 萨曼莎 | 68 | B |
5 | 阿什利 | 63 | B |
select section_,sum(marks)
查询只会决定打印哪些列。决定打印 section_ 和 sum(marks) 列。
section_ | 总和 |
---|---|
D | 185 |
A | 245 |
B | 131 |
order by section_
查询将按升序对行进行排序。
section_ | 总和 |
---|---|
A | 245 |
B | 131 |
D | 185 |
LIMIT 2;
只会打印前 2 行。
section_ | 总和 |
---|---|
A | 245 |
B | 131 |
这就是我们得到最终输出的方式。