【问题标题】:What is easier to read in EXISTS subqueries? [closed]在 EXISTS 子查询中什么更容易阅读? [关闭]
【发布时间】:2011-12-04 08:09:48
【问题描述】:

这是可读性的问题。性能上没有区别。
旧版本的 SQL Server 很傻,可以查找元数据,但现在不行了。

SELECT foo FROM bar WHERE EXISTS (SELECT * FROM baz WHERE baz.id = bar.id);
SELECT foo FROM bar WHERE EXISTS (SELECT 1 FROM baz WHERE baz.id = bar.id);

我没有考虑 NULL 或“有趣的变体”,它们对我来说似乎并不直观。

SELECT foo FROM bar WHERE EXISTS (SELECT NULL FROM baz WHERE baz.id = bar.id); SELECT foo FROM bar WHERE EXISTS (SELECT 1/0 FROM baz WHERE baz.id = bar.id);

刚才在cmets中弹出了这个问题。我研究了最流行的 RDBMS 的手册:

在 SO 上搜索 code:"EXISTS (SELECT 1" 会产生 5,048 个结果。
在 SO 上搜索 code:"EXISTS (SELECT *" 会产生 5,154 个结果。
更新链接和计数 07.2015。

所以SELECT * 拥有大众投票和大型商业 RDBMS。
我发现SELECT 1 更直观。这就像说“如果至少存在一个”。
SELECT * 更直观吗?

【问题讨论】:

  • 为什么SELECT 1 会说“如果至少存在一个”?我认为这根本没有直觉意义。如果有人写了SELECT 2,你会直观地认为这是在检查至少 2 个存在吗?
  • @MartinSmith:你在一句话中使用了 intuitionthinking
  • 也许这些更适合讨论这些非开发概念? linguistics.stackexchange.comphilosophy.stackexchange.com
  • @Erwin,我知道你已经说过你不会考虑select NULL,但我会要求你重新考虑。 only 任何人选择 null 的时间是他们不关心返回的 what - 对我来说,这意味着查询的唯一目的是检查是否存在,因此比任何其他选项都更直观。
  • 您想知道哪个更直观,但这里唯一能增加直观性的地方就是真正的初学者。在我做“Select 1”之前,我有初学者问过我,但他们似乎很直观地理解“Select *”发生了什么。因此,一个提出问题而另一个没有让我相信 * 更直观的事实。

标签: sql syntax exists


【解决方案1】:

直观的是...EXISTS (SELECT * ..,因为您真的不在乎

  • 唯一重要的关键字是EXISTS
  • ...EXISTS (SELECT 1 .. 的选择延续了围绕 EXISTS 的一般神话和迷信(例如 MySQL 文档中的 cmets)。
  • ANSI 标准说“没关系”
  • 了解 EXISTS 是一个半联接会更有趣。

【讨论】:

  • 什么普遍的神话? SELECT 1 有我的投票
  • @EvanCarroll 为什么?
  • (a) 规范将其定义为相同,(b) 它更简洁——您显然不关心列,(c) 不同版本的行为更加一致,一些数据库暂时不要优化条件。
  • 好吧,如果你关心绝对的“干净”,EXISTS (SELECT FROM a) 在 Postgres 中可以正常工作;)
  • 我总是使用EXISTS ( SELECT 'any rows?' FROM...,因为它符合这种语言的精神,像英语一样阅读。
【解决方案2】:

出于历史原因(gbn:这应该歇斯底里吗?),我仍然使用EXISTS (SELECT * ...)。从技术上讲,当然没有区别。优化器/计划器会将其丢弃并将其减少为一点点信息。对于人类读者来说,* 看起来更特别,它将作为一个特殊符号脱颖而出,而不是作为一个值或常数。此外,我倾向于减少程序中 literals 和魔法常数的数量(最终,应该只保留 0 和 1)。

【讨论】:

  • 你的意思是“歇斯底里”还是“历史”……?在谈论神话和迷信时,“歇斯底里”更正确......
  • 双关语是有意的......
【解决方案3】:

EXISTScontext 中,SQL 优化器知道它返回什么并不重要,只要它返回一些东西。所以对你来说没关系。

对于直观的部分:我不认为* 是正确的。

最好用文字问:“检查是否存在最轻微的部分” - 意思是1(或其他东西)。

【讨论】:

  • 这里最细微的部分是一行。这就是EXISTS 检查的内容,如果存在一行。这就是为什么 SELECT *SELECT the-whole-row 对很多人来说看起来更直观的原因。
  • 谢谢。用于纠正。我仍然难以理解@gbn 的答案。如果内部循环执行select *,那么这将在幕后转换为列 - 这需要更多时间。我的解决方案只返回 1。我不关心列。我错了吗 ? (大声笑并删除你这个 93 岁的人 hhhhhh :-)
  • 是的,即使是 MySQL(不是那么聪明)的优化器也知道 EXISTS (SELECT 1 ...)EXISTS (SELECT * ...) 是真还是假,这取决于是否有一行 会被 子查询。换句话说,优化器知道他们不必实际运行子查询并返回一些东西。他们只检查它是否会返回一行。当它位于 EXISTS 中时,可以将其视为“优化器始终以 (SELECT 1 ...) 运行它”。
  • @ypercube 如何检查?我的意思是像 sql 的反射器......?执行计划不会向我显示来自 select *select 1 的这种转换 ....这是我不喜欢 SQL 的那种东西。
  • 每个产品都不同。以 MySQL 为例,请检查:Tracing the Optimizer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-16
  • 1970-01-01
  • 1970-01-01
  • 2013-11-02
  • 2016-01-02
相关资源
最近更新 更多