mysql - 了解 SQL 中的元组语法

标签 mysql sql postgresql subquery

在测试一堆值时,我总是很容易地使用 IN (val1, val2, ...) 语法。但是,我想知道它实际评估的数据结构类型是什么,这是表函数吗?例如:

-- to populate data
CREATE TABLE main_territory (
  name varchar NOT NULL,
  is_fake_territory integer NOT NULL,
  code varchar NOT NULL
);

INSERT INTO main_territory (name, is_fake_territory, code) VALUES ('Afghanistan', 0, 'AF'), ('Albania', 0, 'AL'), ('Algeria', 0, 'DZ');
select '1' as "query#", * from main_territory where code in ('AF', 'AL') union all
select '2' as "query#", * from main_territory where code in (select 'AF' UNION ALL select 'AL') UNION ALL
select '3' as "query#", * from main_territory where code in (select code from main_territory where name ='Albania' or name = 'Afghanistan')

enter image description here

第二个和第三个查询返回一个单列表(这称为标量表吗?),所以我想象 (expr1, expr2, ...) 会做同样的事情东西——它评估为一个单列表。这准确吗?或者这是什么实际数据类型?

最佳答案

我不会调用 IN ( ) 谓词元组比较。元组比较(又名行构造函数比较)的示例是:

WHERE (col1, col2) = ('abc', 123)

或者您甚至可以进行多值行构造函数比较:

WHERE (col1, col2) IN (('abc', 123), ('xyz', 456))

您显示的示例只是 IN ( ) 谓词,它将单个值与值列表进行比较。如果该值与列表中的任何值匹配,则满足谓词。该列表可以是表达式或文字的固定列表:

WHERE code IN ('AF', 'AL') 

或者它可以是子查询的结果:

WHERE code IN (SELECT code FROM ...)

如何实现取决于相应 RDBMS 的代码。它可能必须具体化子查询的结果并将其存储为内部列表。在某些软件中,可能会使用一列的临时表作为数据结构来存储子查询的结果。然后,IN ( ) 谓词可以作为针对该临时表的联接来执行。如果说 SQL 引擎应该能够高效地完成一件事,那就是连接。 :-)

但是如果子查询的结果是数百万行,这可能会很昂贵。在这种情况下,聪明的优化器会“分解”IN ( ) 谓词并只进行连接。也就是说,它将读取 code 的每个值,并对第二个表的 code 列进行索引查找。这意味着本身没有数据结构,它只是连接的评估。

真正的答案取决于实现。 MySQL和PostgreSQL都是开源的,如果想了解具体实现可以尝试下载并自行阅读代码。

关于mysql - 了解 SQL 中的元组语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72094107/

相关文章:

android - SQLITE SUM 和 LIMIT 似乎不能一起工作

javascript - Node js Postgresql - 插入表时出错

sql - Postgresql 时区转换

mysql - 没有得到正确的结果,但在 sql 中工作

sql - 序言到 SQL 转换器

php - 最佳数据库存储方式

mysql - Limit With order by 在mysql中只需要10条记录需要很长时间

sql - postgresql 中的长更新

mysql - SQL Order by 子句不按字母顺序返回

php - 使用 php 解析 mysql 转储文件中的值?