Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.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
Sql id的意外表扫描!=身份证件_Sql_Sql Server_Sql Server 2005_Indexing - Fatal编程技术网

Sql id的意外表扫描!=身份证件

Sql id的意外表扫描!=身份证件,sql,sql-server,sql-server-2005,indexing,Sql,Sql Server,Sql Server 2005,Indexing,一个应用程序会给Sql Server 2005数据库带来沉重的负载我们不控制每分钟运行此查询数百次的应用程序: select id,col1,col2,col3 from table where id != id 注意id!=id,表示一行与其自身不相等。毫不奇怪,结果总是找不到行。但是,Sql Server每次运行此查询时都会执行聚集索引扫描 id列定义为: varchar(15) not null primary key 查询计划显示了大量的“估计行数”。有人知道为什么Sql Serve

一个应用程序会给Sql Server 2005数据库带来沉重的负载我们不控制每分钟运行此查询数百次的应用程序

select id,col1,col2,col3 from table where id != id
注意id!=id,表示一行与其自身不相等。毫不奇怪,结果总是找不到行。但是,Sql Server每次运行此查询时都会执行聚集索引扫描

id列定义为:

varchar(15) not null primary key

查询计划显示了大量的“估计行数”。有人知道为什么Sql Server需要表扫描来找出明显的问题吗?

我不知道为什么id!=在这种情况下,id需要很长时间(虽然“显而易见”是主观的——我认为这不一定是一种优化……这似乎是一个不寻常的问题;但笛卡尔连接是痛苦的)。但一般来说,尝试“where1=0”-或者如果您只是想要模式,可能会有轻微的风险


编辑:刚刚看到“我们不控制每分钟运行数百次此查询的应用程序”。。。六羟甲基三聚氰胺六甲醚。。。这使得它变得棘手。

每个值都与其余的n-1值进行比较。这就是为什么它返回一个巨大的“估计行数”数字的原因。对于上述问题,最好不要在中使用


这篇文章很好地说明了你的问题。我希望它能帮助你

你最大的问题不是表格扫描。你最大的两个问题是:

  • 你有一个对数据库每分钟运行100次的毫无用处的查询。顺便说一句,我的猜测是,正如Marc Gravell所建议的,查询实际上是试图从表中获取列名
更重要的是:

  • 您无法控制访问数据库的用户或内容
第二个问题很可能会让你头疼不已。假设您是组织中数据团队的一员(因为您是试图解决此问题的人),您真的应该考虑进行必要的组织更改以完成您的工作


祝你好运

我会伪造这个查询。。。抽象出一个视图,并复制查询

将现有表“table”重命名为“table_org”或其他名称,并创建如下视图:

CREATE VIEW table
AS
SELECT * FROM table_org
WHERE id='BOGUSKEY'

现在,您应该对主键上的表进行1次扫描,它应该(像原始查询一样)什么也找不到。应用程序不知道什么更明智…

我见过这种类型的查询

最有可能的是,开发人员正在基于用户输入、当前设置或其他因素构建“WHERE”子句。在许多情况下,可能是默认情况下,他们需要一个WHERE子句,它只是一个占位符。这就是他们使用“id!=身份证、11号等

“一分钟数百次”也让我相信这是一个错误的默认占位符

有时,它们会使用一个相反的条件,如果默认情况需要所有行,则该条件的计算结果始终为true


这很难实现,但我的建议是看看您是否可以修改应用程序设置,看看这个查询是否消失。您可能最终得到一个小的结果集,但SQL Server运行频率较低,处理效果更好。

您可能希望让SQL Server支持团队了解此查询(当列定义为主键时为id)及其导致的完整表扫描,并查看他们是否希望在查询引擎中添加优化,以确保这不会导致完整表扫描

或者,或者与你无法控制的应用程序的支持团队交谈


编辑:尝试在TechNet论坛上报告该行为。

id列上是否有非聚集索引?如果不是,最有效的方法就是进行CIX扫描。尝试在ID列上添加一个NCIX-它仍然可以执行扫描,但至少是在一个非常小的索引上进行扫描。如果您使用的是SQL Server 2008,则可以创建一个筛选索引(其中id为),SQL Server将使用(空)筛选索引来满足查询。

由于对SQL Server不太熟悉,我认为下面的解决方案也可以应用于SQL Server


在Oracle中,我认为通过使用物化视图和查询重写,您可以比天真的SQL更聪明。物化视图将不包含行,而查询重写将识别SQL并将查询重新路由到空视图。物化视图永远不需要更新,因为它总是空的。

在阅读了这里的答案和您的编辑之后,让我总结一下您的选择:

  • 更改MS SQL Server以处理此情况(基本上,请与Microsoft支持人员联系)
  • 更改应用程序以避免这种情况,或者以不同的方式进行(基本上,与提出应用程序的公司的支持人员交谈)
  • 更改为处理此情况的SQL Server以外的内容(如果应用程序允许)
  • 更改为其他应用程序
  • 这些都不是好的解决方案,但不幸的是,它们是您仅有的解决方案。你必须选一个,然后跟着它走

    我会先尝试解决方案2,它是需要/应该花费最短时间执行的方案


    另一方面,如果该公司不愿意更改应用程序,那么我会选择解决方案4。这是一个主要的性能缺陷,如果公司不愿意或无法解决这个问题,你必须问问自己,下一个拐角处还隐藏着什么?

    我几乎羞于给出这个答案,但本着“如果没有理智的东西起作用,那就试试疯狂的东西”的精神

    在id=id的表上创建约束? where子句只能返回违反约束的行,根据定义,没有违反约束的行。在您的情况下,此附加(尽管是冗余)信息可能有助于优化人员。它可能同样达到零的平方根,但在你的情况下,我会尝试一下,以防万一…