SQL查询如何工作?

时间:2010-03-18 07:47:02

标签: sql

SQL查询如何工作? 它是如何编译的? 首先编译from子句以查看表是否存在? 它是如何从数据库中实际检索数据的? 表格存储在数据库中的方式和格式是什么?

我正在使用phpmyadmin,有什么方法可以查看存储数据的文件吗? 我正在使用MySQL

5 个答案:

答案 0 :(得分:13)

嗯...

  • 首先进行语法检查,然后生成表达式树 - 在此阶段,您还可以测试元素是否存在和“排队”(即表中是否存在字段)。这是第一步 - 任何错误都可以告诉提交者真实。
  • 然后你有....分析。 SQL查询与程序的不同之处在于它没有说如何做某事,只是结果是什么。设置基于逻辑。因此,您可以获得一个查询分析器(取决于产品不好 - oracle长期以来一直很糟糕,DB2是最敏感的,甚至是测量光盘速度)来决定如何最好地接近这个结果。这是一个非常复杂的野兽 - 它可能会尝试数十种或数百种方法来找到他认为最快的方法(基于成本,基本上是一些统计数据)。
  • 然后执行。

顺便说一句,查询分析器是您看到巨大差异的地方。不确定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查询处理阶段。

enter image description here

注意-在执行计划之前,它还会对变量的值执行 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

但是我们是如何得到这个输出的?

我已经逐步解释了查询。请阅读以下内容:

1. FROM , WHERE 子句执行

因此 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

2. GROUP BY 子句执行

现在 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

3. HAVING 子句执行

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

3. SELECT 子句执行

select section_,sum(marks) 查询只会决定打印哪些列。决定打印 section_ 和 sum(marks) 列。

<头>
section_ 总和
D 185
A 245
B 131

4. ORDER BY 子句执行

order by section_ 查询将按升序对行进行排序。

<头>
section_ 总和
A 245
B 131
D 185

5. LIMIT 子句执行

LIMIT 2; 只会打印前 2 行。

<头>
section_ 总和
A 245
B 131

这就是我们得到最终输出的方式。