多年来,我了解到当连接表时,主表中的一行在应用条件后连接到目标表中的一行,即查询结果将<=主表中的行。但是我已经看到主表中的一行可以在条件允许的情况下多次连接。例如,如果没有主表中的重复行,下面的查询的计数函数将无法工作
SELECT node.name, (COUNT(parent.name) - 1) AS depth
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;
产生这个结果
+----------------------+-------+
| name | depth |
+----------------------+-------+
| ELECTRONICS | 0 |
| TELEVISIONS | 1 |
| TUBE | 2 |
| LCD | 2 |
| PLASMA | 2 |
| PORTABLE ELECTRONICS | 1 |
| MP3 PLAYERS | 2 |
| FLASH | 3 |
| CD PLAYERS | 2 |
| 2 WAY RADIOS | 2 |
+----------------------+-------+
我知道我可能会问一些非常基本的东西,但是如何在最简单的连接中将行连接在一起,mysql 是否采取诸如正则表达式引擎针对字符串执行模式之类的步骤?
如何"实现连接实际上并不重要。 SQL是一种描述性语言,而不是过程语言。 查询引擎可以决定"如何"。 查询描述的是"什么"。
内部联接的概念定义相当简单。 它是满足on
和where
子句条件的两个集合的笛卡尔乘积。
大多数人不会从笛卡尔乘积的角度思考。 嵌套循环是等效的。 逻辑是这样的:
for each row1 in table1
for each row2 in table2
output row1 || row2 if the on/where conditions are true
外连接扩展了此概念,允许一个或两个表中的行位于结果集中,即使on
/where
条件不为真。
没有任何关于"查询结果将<=主表中的行"的概念。 对于某些数据结构(特别是连接了维度表的事实数据表),您将获得该行为。 但是,这是因为数据模型是为此目的而设计的,而不是因为SQL以这种方式工作。
我的两分钱。我同意"如何"并不重要,因为SQL是一种描述性语言。井。。。这并不重要,直到您的查询在系统成功且数据库增长(很多)时变得缓慢(我的经验)。
如果您需要找出SQL运行缓慢或无响应的原因,则需要了解数据库在后台的工作方式。数据库使用多种策略来联接表。通常(不是完整列表):
- 嵌套循环连接"NLJ">:这是你提到的那个。 合并联接
- :"并排">联接表。 哈希
- 联接:对一个表进行哈希处理,然后在另一个表上执行扫描。
- N-Ary Join:类似于NLJ,但同时具有两个以上的表。
根据表的大小、列统计信息、筛选器的选择性(其中)数据库可以使用其中之一。如果列统计和值分布发生变化,它甚至可以随着时间的推移而变化。
如果您想了解这些策略是什么,以及当每个策略都方便时,您可以开始使用
EXPLAIN <sql>
查看MySQL用于特定查询的策略。然后,您可以阅读数据库理论以了解幕后的细节。