我正在运行一个简单的更新语句。执行时间太长。以下是更新和索引详细信息。
Exported列的默认值为0
UPDATE PAR_ITM SET exported = -1 WHERE exported < 1
索引:
CREATE NONCLUSTERED INDEX [IX_PAR_ITM_Exported_1]
ON [dbo].[PAR_ITM] ([exported] ASC)
WITH (
PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = ON, SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80
) ON [PRIMARY]
答案 0 :(得分:3)
因此,您将导出设置为-1,其中导出已经等于-1。也许将您的are子句更改为WHERE exported = 0会更少的行?
答案 1 :(得分:3)
基数低
您正遇到一个名为low cardinality
的问题
见wikipedia。
问题
简而言之,每个数据库(我知道)都会拒绝在低基数列上使用索引。
还有更多
良好 数据库如果猜测选择 (选择的低基数)将会击中很多行,也会拒绝使用索引< / strong> ,即使列本身有很多不同的值 (列的高基数)
为什么 - 在这里插入数据库 - 不使用索引?
这是问题所在
如果数据库中所有行的超过50%(每个数据库不同)具有相同的值,则DB将不使用索引,因为使用索引是没有意义的。
对于大多数行执行2次读取是没有意义的(如果您可以执行一次读取(在表格本身上),则对索引读取1,对表格读取2)。 无论如何,数据库必须读取大多数行,所以它只是继续读取它们 数据库必须使用其最慢的访问机制(全表扫描)后退这一事实导致您的速度变慢。
解决方案
增加列的基数或增加选择的基数
在其他工作中,请确保选择少于50%的所有行,并确保SQL服务器知道(或可以猜测)这一点。
数据库如何知道列的基数?
一个好的DB在执行选择/更新/插入时保持表和列的统计信息。通过这种方式,它具有做出明智决策所需的信息。
强制使用索引会加快查询速度吗?
不,它会减慢速度。
SO链接
MySQL: low cardinality/selectivity columns = how to index?
Indexing & alternatives for low-selectivity columns
答案 2 :(得分:1)
可能有助于了解其中包含的记录数量:
Select Count(*)
FROM PAR_ITM
WHERE exported < 1
基本上要更新多少行。当然,即使一百万行也会相对较快地完成。
其他类型的查询是否在您的服务器上执行缓慢?
答案 3 :(得分:1)
我认为你不应该在这里使用非聚集索引,因为它似乎根本没有exported
的唯一性。非聚集索引的经验法则是95%唯一性,因为查询优化器可能不会使用索引,这意味着您无缘无故地放慢速度。
请查看本文以获取有关非聚集索引的说明:
http://www.sql-server-performance.com/2007/nonclustered-indexes/
答案 4 :(得分:1)
您还可能涉及另一个查询的阻止情况。