删除查询中包含大表的 IN 子句中的子查询性能

Posted

技术标签:

【中文标题】删除查询中包含大表的 IN 子句中的子查询性能【英文标题】:Performance of sub-query in IN clause with large tables in delete query 【发布时间】:2017-01-30 18:59:15 【问题描述】:

我想知道,为什么使用 IN-Operator 的查询比简单的 SELECT 慢得多。

让我通过一个例子来证明我的观察:

Query1: SELECT VIDEO_ID FROM videos (about 8000 rows with 1 column)

Query2: DELETE FROM video_snapshot WHERE video_snapshot.VIDEO_ID IN (Query1)

video_snapshot 是一个非常大的表,包含超过 7.000.000 行,但 VIDEO_ID 已编入索引,因此在 WHERE 子句中使用 VIDEO_ID 的查询足够快。

IN-Operator 是如何工作的?我猜这只是几个WHERE 子句的简短形式。

我在 XAMPP 上使用 MariaDB 10.1.16

【问题讨论】:

也许这个可以帮到你:***.com/a/14194444/1050927 解释说明了什么 速度很慢,因为您正在执行相关子查询。请注意,您从未提供过分析模式。对于任何相关表,这将通过show create table xyz 完成。你也没有给Query1。所以这不是很有帮助 【参考方案1】:

对于大型数据集表IN 子句性能很慢,在这种情况下您可以使用INNER JOIN 与删除查询

DELETE video_snapshot FROM video_snapshot
INNER JOIN videos ON video_snapshot.VIDEO_ID=videos.VIDEO_ID;

根据我的经验,IN 是一个非常慢的运算符,因为 SQL 通常 将其评估为一系列由“OR”分隔的 WHERE 子句(WHERE x=Y OR x=Z OR...).. 但主要是显式连接在需要将字段与其他表字段进行比较时更快。

【讨论】:

这个查询非常快。谢谢你。为什么IN 处理大数据集的速度这么慢?

以上是关于删除查询中包含大表的 IN 子句中的子查询性能的主要内容,如果未能解决你的问题,请参考以下文章

MySQL的子查询中FROM和EXISTS子句的使用教程

SQL - 聚合可能不会出现在 WHERE 子句中,除非它位于 HAVING 子句中包含的子查询中

多对多关系 - 大表的查询性能

Mysql语句优化

如何解决大量数据的 IN 子句 SQL 查询中的性能问题?

大表的mysql性能问题