IN运算符对SQL查询性能有多糟糕?

时间:2011-06-23 17:23:11

标签: sql performance operator-keyword

我的SQL查询花了9个小时执行。见下文:

Select Field1, Field2
From A
Where Field3 IN (45 unique values here) 

当我将此查询拆分为3个完全相同的查询时,每个查询只有IN子句中的15个值,它们每个都需要2分钟才能执行。 因此,我花了6分钟(3个查询* 2分钟)而不是花费9个小时。

任何人都可以解释一下,实际上相同的查询只有IN子句中值的差异才能运行不同的时间吗?

5 个答案:

答案 0 :(得分:2)

  • 您使用的是什么数据库引擎(Oracle,SQL Server,MySQL等)?
  • 您可以发布两个查询的查询计划吗?

听起来您的数据库使用的优化器为第一个查询选择了一个非常糟糕的执行计划。假设您的数据库引擎使用某种基于成本的优化器(大多数大型供应商都这样做),这通常意味着优化器猜测返回的行数是非常不正确的。最有可能的是,无论是否指定了15或45个唯一值,其估计值同样不正确,但实际上,错误估计值增加三倍会导致优化程序认为不同的查询计划是合适的。通常,这意味着您在表A的统计信息方面为优化程序提供的信息不正确,需要修复。

话虽如此,表格A有多大?如果您确实从单个表中查询,则优化器的选项相对较少。它实际上只需要决定在A上进行全表扫描和在Field3上使用索引。即使它决定进行表扫描而不是使用Field3上的索引,也不可能花费9个小时来扫描单个表,除非测量表A的特殊情况至少数百GB,硬件相对行人。

答案 1 :(得分:2)

您是否尝试使用EXISTS

 Select Field1, Field2 From A Where
 EXISTS (SELECT NULL FROM B Where
 B.value = A.Value )

答案 2 :(得分:1)

我可以看到两种可能性:

1)Field3 = 10001可能有十亿条记录,所以这些记录确实很慢。并且可能没有其他值的记录,因此速度非常快。

2)问题可能是数据库用于运行查询的方法。例如,可能存在切断点,它可能会从使用索引切换到全表扫描。优化器并不总是正确的。当它出错时你必须围着它跳舞。

答案 3 :(得分:0)

查询性能不佳可能是由许多不同的问题造成的,我甚至不敢冒险猜测是你的问题,因为没有足够的信息:

  • 多个或不必要的联接
  • 已连接表格的行计数
  • 查询引擎没有使用索引或索引
  • 过时表统计信息导致索引效率低下
  • 效率低下的查询

说到这一点,您总是可以通过运行EXPLAIN PLAN来更好地了解查询引擎如何解释您的查询。以下是有关如何为Oracle数据库http://download.oracle.com/docs/cd/B10500_01/server.920/a96533/ex_plan.htm

执行此操作的信息

答案 4 :(得分:0)

首先,确保表“A”中的“Field3”有索引,如果可能,请包含“Field1”,“Field2”(覆盖索引)。您没有说明您正在运行哪个数据库,因此很难准确地提供更好的建议。

如果仍然没有加快速度,请尝试创建临时表,然后将所有“IN”值插入“INNER JOIN”或“WHERE EXISTS”临时表到表“A”。