在SQL Server中将大表连接到小型集群的列存储索引需要太长时间

时间:2017-12-16 12:09:25

标签: sql sql-server join azure-sql-database inner-join

尝试连接2个表时,我的性能非常慢:一个有39M行,另一个有10k(35秒)。这在Azure SQL Premium实例上运行,这是非常不错的服务器

select m39.* 
from [Table_With_39M_Rows] m39 
inner join [Table_With_10K_Rows] k10 on m39.[Id] = k10.[Id] 

即使count(*)需要大约10秒

select count(*) 
from [Table_With_39M_Rows] m39 
inner join [Table_With_10K_Rows] k10 on m39.[Id] = k10.[Id] 

以下是表格详情:

  • [Table_With_39M_Rows]有大约3900万行(50列)和一个聚簇列存储索引:

    CREATE CLUSTERED COLUMNSTORE INDEX CCI_Table_With_39M_Rows 
       ON Table_With_39M_Rows
    CREATE UNIQUE NONCLUSTERED UNCI_Table_With_39M_Rows_Id (Id ASC)
    
  • [Table_With_10K_Rows]有大约10k行(50列)和Id作为主键

    ALTER TABLE Table_With_10K_Rows 
        ADD CONSTRAINT PK_Table_With_10K_Rows 
        PRIMARY KEY CLUSTERED([Id] ASC)
    

enter image description here

Clustered ColumnsStore索引扫描占用99%并减慢所有内容。

如何优化此特定加入?我应该采用什么索引策略?

2 个答案:

答案 0 :(得分:0)

如果行组删除工作,则群集存储索引是有用的(您可以认为这跳过了不满足谓词的整个行段)以及查询本质上是分析性的。 / p>

要检查是否正在删除段,您可以使用以下查询

以下是我所拥有的查询的示例演示(因为我们没有您的测试数据)可能有助于您了解更多

查询:

select s.* from sales s
join
numbers n
on n.number=s.id

Numbers表只有65356行,sales表有超过300万行。每个段只能有一百万行。如果你能看到statistics IO的输出,SQLSERVER读取2段(200万行)并且跳过2个段,这不是很好,我希望只读取一个段,剩下三个段要跳过。但是如下所示读取2个

Table 'sales'. Segment reads 2, segment skipped 2.

这种情况正在发生,因为您可能已经从堆创建了集群列存储,因此请尝试执行以下操作

删除你存在的聚簇列存储索引,在我的例子中是

drop index nci on sales

现在尝试先创建聚簇索引,然后尝试创建聚簇列存储,这有助于sqlserver按行顺序插入行进入聚簇列存储索引..您可能还想使用maxdop 1来避免并行和无序行

create clustered index  nci on sales(id)

create clustered columnstore index nci  on sales
with (drop_existing=on,maxdop =1)

如果您现在运行查询,您可以看到发生分段消除和查询快速

Table 'sales'. Segment reads 1, segment skipped 2.

参考文献和进一步阅读:
https://www.sqlpassion.at/archive/2017/01/30/columnstore-segment-elimination/ https://blogs.msdn.microsoft.com/sqlserverstorageengine/2016/07 / 17 / columnstore-index-how-do-they-defer-from-traditional-btree-indices-on-rowstore-tables /
https://blogs.msdn.microsoft.com/sql_server_team/columnstore-index-performance-rowgroup-elimination/

答案 1 :(得分:0)

我建议你在使用[]时保持一致。

外键的ID不是一个好名字。

Columnstore Indexes Described

  

Columnstore索引可为使用的查询提供高性能增益   全表扫描,并不适合寻求的查询   数据,搜索特定值。

仅仅因为你需要将columnstore用于其他目的并不能使它成为一个很好的应用程序。

在[Table_With_39M_Rows]上尝试常规的非聚集索引。[ID]