Jas*_*son 9 sql-server columnstore sql-server-2016
我想通过创建聚集列存储索引将行存储表转换为列存储表。表中有三列:id、time 和 value。
该表在创建列存储索引之前按 id 和时间排序;但是,在创建列存储索引后,行顺序混乱了。我认为这可能是由于并行性并添加了maxdop = 1选项,但这并没有解决问题。谁能帮我这个?
这是创建表和索引的代码:
-- creating rowstore table
drop table if exists tab1_rstore
select id, time, value
into tab1_rstore
from tab0
order by id_loan, period
option(maxdop 1)
-- creating clustered index on rowstore table
create clustered index idx on tab1_rstore (id,time)
-- creating columnstore table
select *
into tab1_cstore
from tab1_rstore
option(maxdop 1)
-- comparing the first two rows from these two tables
select top 2 *
from tab1_rstore
select top 2 *
from tab1_cstore
Run Code Online (Sandbox Code Playgroud)
查询结果截图:
-- creating clustered columnstore index
create clustered columnstore index idx on tab1_cstore
with (maxdop = 1)
-- comparing the top two rows again
select top 2 *
from tab1_rstore
select top 2 *
from tab1_cstore
Run Code Online (Sandbox Code Playgroud)
带有列存储索引的查询结果截图:
我的理解是行的顺序是由压缩算法决定的,我们对此无能为力,请参阅此处文档中的限制和限制,并引用以下内容:
不能包含用于对索引进行排序的 ASC 或 DESC 关键字。列存储索引根据压缩算法进行排序。排序会消除许多性能优势。
我在 Windows 10 64 位上使用 SQL Server 2016 开发人员版。
Pau*_*ite 15
聚集列存储索引与聚集行存储索引根本不同。您可能已经注意到聚集列存储索引没有键列规范。没错:聚集列存储索引是一个没有键的索引 - 所有列都被“包含”。
我听到的关于聚集列存储索引的最直观的描述是将其视为面向列的堆表(其中 'RID' 是rowgroup_id, row_number)。
如果您需要索引来支持直接排序和/或点/小范围选择,您可以在 SQL Server 2016 中的聚集列存储之上创建可更新的行存储 b 树索引。
在许多情况下,这根本没有必要,因为列存储访问和批处理模式排序非常快。人们需要为列存储重新学习人们“了解”的许多关于行存储性能的知识。扫描和哈希很好:)
也就是说,当然,列存储的行组(以及每个段中关于最小值/最大值的元数据)有一个结构,这在可以从行组/段消除中受益的查询中非常有用。
该领域的一项重要技术是首先创建具有所需顺序的聚集行存储索引,然后使用该WITH (DROP_EXISTING = ON, MAXDOP = 1)选项创建聚集列存储索引。在你的例子中:
CREATE [UNIQUE] CLUSTERED INDEX idx
ON dbo.tab1_cstore (id, time)
WITH (MAXDOP = 1);
CREATE CLUSTERED COLUMNSTORE INDEX idx
ON dbo.tab1_cstore
WITH (DROP_EXISTING = ON, MAXDOP = 1);
Run Code Online (Sandbox Code Playgroud)
需要注意随着时间的推移保持行组/段消除的好处。此外,虽然列存储已经按行组进行了隐式分区,但您也可以对其进行显式分区。
我不是 100% 确定您要测试什么,但是段内值的“顺序”确实由压缩算法确定。我关于创建列存储索引的观点DROP_EXISTING是关于流入段创建过程的数据的排序,以便整个段将以特定方式排序。在该细分市场内,所有赌注都已关闭。