即使在简单计数(*)上,包含120万行和400多列的SQL Server表也非常慢

时间:2012-02-10 14:27:19

标签: performance sql-server-2008 tsql

我使用SQL Server 2008 R2并从DB2表中复制了一个表。我知道行数不正常,但这是历史性的,我现在无法做任何事情。

但是简单的行数需要超过2分钟。该表由3列和索引的客户ID组成,其余为具有十进制数字的字段。

像这样的搜索:

select 
    AD_ARBNUM, AD_SHBETSA, AD_AMBIDSHBETSA,AD_ASKATSHBETSA
from 
    lmoko 
where 
    AD_SHBETSA + AD_AMBIDSHBETSA + AD_ASKATSHBETSA < 0

其中AD_ARBNUM已编入索引,其余为十进制需要3分钟以上。

如果在DB2中运行,则在20秒内运行相同的查询。 (我不知道关于DB2部分的索引)

有关提高性能的建议吗?

3 个答案:

答案 0 :(得分:2)

WHERE子句将三个不同的列一起添加,然后将它们与值进行比较。为了做到这一点,SQL SErver必须扫描整个表。针对这样的列的任何类型的函数都将导致对表的扫描。随着表的增长,查询将变得更慢和更快慢。

您可以创建computed column。假设您正在运行2005或更高版本,您还可以添加index on that column

答案 1 :(得分:1)

(我的回答充实了前几条评论,仅提供详细信息和一些背景信息。)

SQL索引用于&#34;查找&#34;具体价值。使用AD_ARBUM上的索引,SQL将在几乎没有时间内找到具有特定值(例如12)的所有行(当然,除非表的行的一半设置为12,在这种情况下,您&#39 ;我必须读一半的表)。您的查询过滤器基于基于多个列的公式,其中没有一列被编入索引,因此需要读取所有这些列(跨所有1.2百万行),以评估要包含哪些列,哪些不包含。如果您在所有三个公式列中构建了索引 (AD_SHBETSA,AD_AMBIDSHBETSA,AD_ASKATSHBETSA),它仍然必须在每个上做相同的数学公式。如果你在公式本身上建立了一个索引

CREATE nonclustered INDEX IX_lmoko__ThreeColumnFormula
 on lmokok (AD_SHBETSA + AD_AMBIDSHBETSA + AD_ASKATSHBETSA

然后SQL可以根据你关心的值进行搜索和过滤,并且速度要快得多(当然,假设你最终没有返回所有行。)这样做的缺点是索引是你必须维护索引;它会占用空间,它可以减慢插入和更新速度,如果它只用于查询,则每月运行一次(而不是每分钟一次),性能和资源成本可能过高。

另外,正如所指出的,可能还有其他因素,从糟糕的硬件到资源争用再到整体空间(行有多宽?实际涉及多少列?是那些数值,还是SQL必须转换来自字符串?我们无法在不查看系统的情况下了解很多潜在的问题

答案 2 :(得分:0)

如果您只是担心计数,可以运行:

SELECT SUM (row_count) 
FROM sys.dm_db_partition_stats 
WHERE object_id = OBJECT_ID('lmoko ') AND (index_id=0 or index_id=1);

另外,除了索引之外,您还可以使用表格,例如创建分区来存储旧数据。