Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql EXISTS和JOIN之间的差异用于检查记录的存在性_Mysql_Sql_Performance_Join_Exists - Fatal编程技术网

Mysql EXISTS和JOIN之间的差异用于检查记录的存在性

Mysql EXISTS和JOIN之间的差异用于检查记录的存在性,mysql,sql,performance,join,exists,Mysql,Sql,Performance,Join,Exists,请看以下示例: SELECT * FROM customers WHERE EXISTS (SELECT * FROM order_details WHERE customers.customer_id = order_details.customer_id) ; 检索相同resultset的两个表之间基于等效内部联接的查询有哪些区别 我关心的是技术/性能方面,而不是代码的可读性/可维护性 for x in (select * from customers) loo

请看以下示例:

SELECT *
FROM customers
WHERE EXISTS
    (SELECT *
     FROM order_details
     WHERE customers.customer_id = order_details.customer_id)
;
检索相同resultset的两个表之间基于等效内部联接的查询有哪些区别


我关心的是技术/性能方面,而不是代码的可读性/可维护性

for x in (select * from customers)
loop
      -- check if x.customer_id exists in order_details table.    
      ---if yes 
          --output the customer tables row
      -- else 
         --ignore 
end if;
end loop;
for x in (select * from customers)
loop
  --for each row in customer 
  -- fetch records from order_details which match this condition
      select * from order_details where customer_id=x.customerid     
end loop;
因此,在exists查询中,计划通常使用嵌套的循环,而不是硬性的规则

JOIN查询的逻辑等价物如下所示

for x in (select * from customers)
loop
      -- check if x.customer_id exists in order_details table.    
      ---if yes 
          --output the customer tables row
      -- else 
         --ignore 
end if;
end loop;
for x in (select * from customers)
loop
  --for each row in customer 
  -- fetch records from order_details which match this condition
      select * from order_details where customer_id=x.customerid     
end loop;
通过EXISTS子句,您可以选择至少存在一条订单详细信息记录的所有客户

SELECT * 
FROM customers c
WHERE EXISTS (SELECT * FROM order_details od WHERE od.customer_id = c.customer_id);
加入后,您将再次选择这些客户。但是,只要存在订单详细信息,您就可以经常选择它们。也就是说,你会有很多副本

SELECT c.*
FROM customers c
JOIN order_details od ON c.customer_id = od.customer_id;
您可以使用DISTINCT从结果中删除重复项,以便再次获得每个客户:

SELECT DISTINCT c.*
FROM customers c
JOIN order_details od ON c.customer_id = od.customer_id;
但是为什么生成所有的重复项只需要再次删除它们呢?不要这样做。仅当您确实想要联接结果时才联接

另一个选项,我认为它比一个存在子句更可读,顺便说一下In子句。这将是我编写查询的方式:

SELECT * FROM customers WHERE customer_id IN (SELECT customer_id FROM order_details);
存在称为半联接。它启动一个联接,但在找到第一个匹配项时停止。因此,EXISTS将比任何等效联接都快

此外,还存在选择*。。。哪里真的不在乎*。它将使用任何最佳索引来发现是否存在与WHERE匹配的行,然后返回1或0表示true或false


当然,如果左连接将返回0或1行,而不是更多,那么性能差别就不大。除了左联接将返回表中的值之外。

联接可能会产生重复的值。除了前面的注释外,带有select*的联接将返回两个表中的所有字段,如果在客户和订单详细信息中更新了统计信息,我就不必担心EXISTS over JOIN的性能,而只是客户,它将是您查询中返回的数据。SQL是一种声明性语言,试图找出如何获取数据的工作最好留给优化器。作为SQL的用户,我们应该考虑QueryExists的逻辑和语义良好性,因为它更易于阅读和优化。另外,它不鼓励在子查询中使用NOT IN。