Sql 如果where条件为!=,则不使用数据库索引?

Sql 如果where条件为!=,则不使用数据库索引?,sql,database,Sql,Database,我在一个列上有一个索引,在查询完成时正确使用它 select * from Table where x = 'somestring' 但是,当查询类似于 select * from Table where x != 'someotherstring' 这是正常的还是我在查询中遗漏了什么?实际的查询当然要大得多,因此它可能是由其他因素引起的。有没有其他办法解释为什么不在查询中使用索引?这确实很正常-要使用索引,需要使用精确匹配(如“=”等于运算符)或类似范围查询的内容 一个定义了“否定”条件(

我在一个列上有一个索引,在查询完成时正确使用它

select * from Table where x = 'somestring'
但是,当查询类似于

select * from Table where x != 'someotherstring'

这是正常的还是我在查询中遗漏了什么?实际的查询当然要大得多,因此它可能是由其他因素引起的。有没有其他办法解释为什么不在查询中使用索引?

这确实很正常-要使用索引,需要使用精确匹配(如“=”等于运算符)或类似范围查询的内容


一个定义了“否定”条件(不是某个或另一个)的查询通常不能通过索引查找得到满足-您必须查找除某个值之外的所有内容。这并不能很好地工作-通常情况下,全表扫描(SQL Server中的聚集索引扫描)会更快,只需检查要匹配的条件(或者在这种情况下不匹配)。

您没有说您使用的是什么数据库引擎

例如,MS SQL Server既有
相等索引
又有
不等索引

后者在
不相等
运算符起作用时使用。

这是正常的。只有当您具有“=”条件时,才会使用索引。正在搜索的索引!=条件无效

类似地,这可能会使用索引(在Oracle中)

但这不会

select * from Table where x like '%thing%'
而且,
从表中选择*,其中x介于1和10之间
将使用索引

但不是
从x不在1和10之间的表格中选择*这是绝对正常的。索引用于查找确切的内容。当我告诉你不要以“S”开头时,我让你查字典,你从哪里开始

你总是可以这样做的

select * from Table a
where not exist (select * from table b where x = 'somestring' and a.key = b.key)

我想那是一个条件可以使用索引(在MSSQL中)。根据MSSQL中的执行计划,如果我在单个字段上有一个索引,并在该字段上应用where子句,则其中一个带有!=如果索引是群集的,并且索引属性没有太多不同的值(因此我们可以快速确定可以跳过哪些块),则可以使用索引。但是,如果索引属性是一个键,那么在这种情况下使用索引是毫无意义的。

看看下面的一个答案,我在Oracle方面有很多经验。我是从这个角度来回答的。稍微概括一下这个特定的案例,可能太聪明了,妨碍了优化引擎。即使列上有索引,查询优化器也不会总是选择使用它。如果您认为优化器犯了错误,您可以在查询中使用“Tom Kyte”,并收集一些经验证据。如果证据表明更改将改进查询,则可以使用微妙的重写,在Oracle的情况下,还可以使用“提示”强制优化器。这是不对的,它取决于数据基数,因为优化器将决定索引成本是否优于where语句扫描,因此如果“someotherstring”的记录数是巨大的,它也会起作用,但如果不是这样,优化器会认为它不值得,并切换到使用where进行扫描。Sql Server中绝对没有“相等”和“不相等”索引,任何版本。不确定你指的是什么?是的。是我的错。我指的是查询计划器检测字段的相等和不相等使用;索引并不区分这两种情况,但根据我的经验,这两种操作符都使用索引。(例如:sys.dm_db_missing_index_details中的SELECT语句、相等_列、不相等_列;将从查询计划器中显示缺少的索引)您希望通过在该查询中使用索引获得什么?这会加快全表扫描吗?因为执行x='somestring'很快,但是执行“where not exist”几乎和完整表扫描一样慢?
select * from Table a
where not exist (select * from table b where x = 'somestring' and a.key = b.key)