这是我的要求:
SELECT TOP 10 * FROM BigTable WHERE值<> 2;
BigTable有点特别,因为Value列包含每行的相同值:2.在实际情况中,可能有一些行具有不同的值,但不是很多.我确实需要找到这些流氓行.但是,我不知道在设计时哪个值(2只是一个例子)(但我知道在查询时).
请求很慢(大约5分钟); BigTable包含1000万行.
所以我在Value列上添加了一个索引,它的类型为smallint. 10分钟后,索引建成了,我再次运行了请求.它仍然很慢.
这个问题可以在这里复制:http://sqlfiddle.com/#!6/6ce0f/1
此时,我的猜测是SQL Server无法使用带有<>的查询的索引运算符,但我不确定为什么?例如,此另一个查询只需2秒:SELECT TOP 10 Value FROM BigTable GROUP BY Value(并返回单行,其值为2).
我正在考虑拆分成多个查询:一个用于获取不同值的列表,另一个用于获取所有流氓行,例如SELECT TOP 10 * FROM BigTable WHERE Value = x等(所有值都不是2) ,但有更好的解决方案吗?
编辑:
此查询的想法是查找在更新大多数行的进程之后尚未更新的行.基本上,我正在与另一个数据源同步.每次运行此过程时,我都会增加该值,并使用新值(以及更新的数据)更新每一行.在该过程结束时,我可以检查哪些行具有旧值,并删除它们.这个过程有点长,这就是为什么我不想先截断表并插入后,因为我需要先前的数据在这个流程执行期间保持可用.
索引是使用此请求创建的(由Entity Framework Core生成,但我手动进行查询测试):
CREATE NONCLUSTERED INDEX [IX_Value] ON [dbo].[BigTable]
(
[Value] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
编辑2:
以下是来自SSMS的估计查询计划(没有什么是绝密的,但由于我没有问我是否可以透露项目的内容,我已经模糊了数据库名称;在这些屏幕截图中,表格和列名称都是真实的那些)