Zac*_*her 8 sql-server count sql-server-2012
我们正在使用在 SQL Server Enterprise 上运行的供应商应用程序,它COUNT
在处理大多数财务文档(订单、发票等)时在 Items 表上执行语句有一个相当烦人的怪癖。
例如 SELECT COUNT('A') FROM [dbo].[Items] T0
我相信这通常没问题,但是有超过 600 万条记录,并且需要大约 400 毫秒来计算它们。这可能构成整个处理时间的很大一部分。
该表已经有一个非常窄的非聚集索引(tinyint,加上聚集键),这是 SQL 在执行表扫描时使用的,所以我认为我们在这方面不能做得更好。
我知道有一些解决方案,如果可能,我们希望避免:
COUNT_BIG(*)
我们还有其他选择可以加快速度吗?
这是显示设置的要点:https : //gist.github.com/elvishfiend/5094f120b14f8ecfb325623edcb5f3eb
Pau*_*ite 14
如果以最佳方式实施,索引视图应该是最快的选项之一,具有最低的维护开销。
正如我在执行计划中的索引视图维护中详细解释的那样,修改是增量(增量)(不会对每个基表更新执行完整的重新计数);但是,您确实需要确保执行计划的增量更新部分具有有效的访问方法(如任何查询)。
从INSERT/UPDATE/DELETE
执行计划中识别缺失的索引通常非常简单。也许您可以在问题中添加说明性的执行后(实际)执行计划。
查询文本与索引视图的自动匹配仅在企业版(和同等版本)中可用。在其他版本中,您必须使用WITH (NOEXPAND)
表提示。即使在企业版上也有很好的理由使用NOEXPAND
。
关于演示代码:确保使用WITH (NOEXPAND)
. 您编写它的方式NOEXPAND
被解析为别名。另请注意,只有物化(索引)视图可以有NOEXPAND
提示。
如果您无法直接添加提示,这将是计划指南的绝佳用途。计划指南还可用于确保与索引视图匹配的查询(无需明确命名)实际使用索引视图。
请记住,如果没有NOEXPAND
物化(索引)视图,SQL Server 总是在计划编译开始时扩展视图定义。企业版可能(也可能不)将查询(部分)与索引视图匹配,具体取决于其对每个选项成本的评估。
相关问答:
如果您坚持使用 SQL Server 2012,您可以尝试仅在聚集索引键上创建索引。它可能比TINYINT
列上的索引小一点。您也可以尝试向索引添加页面压缩。这可能会使您的查询更快,但这取决于表中的数据。
如果您能够升级到 SQL Server 2016,则可以在表上创建非聚集列存储索引。这将使COUNT(*)
查询速度极快,同时降低 DML 操作的开销。这是一个快速演示:
DROP TABLE IF EXISTS #Items;
CREATE TABLE #Items (
CLUST_KEY BIGINT NOT NULL,
SMALL_COLUMN TINYINT NOT NULL,
FILLER VARCHAR(50) NOT NULL,
PRIMARY KEY (CLUST_KEY)
);
INSERT INTO #Items WITH (TABLOCK)
SELECT
ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
, 1
, REPLICATE('Z', 50)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
CREATE INDEX NCI ON #Items (SMALL_COLUMN);
SET STATISTICS TIME ON;
-- CPU time = 312 ms, elapsed time = 320 ms.
SELECT COUNT(*)
FROM #Items
OPTION (MAXDOP 1);
CREATE NONCLUSTERED COLUMNSTORE INDEX NCCI ON #Items (SMALL_COLUMN);
-- CPU time = 0 ms, elapsed time = 1 ms.
SELECT COUNT(*)
FROM #Items
OPTION (MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)
使用 NCCI,我可以在 20 毫秒内计算出 600 万行。
归档时间: |
|
查看次数: |
10009 次 |
最近记录: |