SqlServer 性能优化Partition(创建分区)
和压缩(Compression)相比,数据库分区(Partition)的操作更为复杂繁琐。而且与Compression一次操作,终身保持不同,分区是一项需要长期维护周期变更的操作。 分区的意义在于将大数据从物理上切割为几个相互独立的小部分,从而在查询时只取出其中一个或几
和压缩(Compression)相比,数据库分区(Partition)的操作更为复杂繁琐。而且与Compression一次操作,终身保持不同,分区是一项需要长期维护周期变更的操作。
分区的意义在于将大数据从物理上切割为几个相互独立的小部分,从而在查询时只取出其中一个或几个分区,减少影响的数据;另外对于置于不同文件组的分区,并行查询的性能也要高于对整个表的查询性能。
事实上,在SQL Server 2005中就已经包含了分区功能,甚至在2005之前,还存在一个叫做“Partitioned Views”的功能,能通过将同样结构的表Union在一个View中,实现类似现在分区表的效果。而在SQL Server 2008中,分区功能得到了显著加强,使得我们不仅能够对表和索引做分区,而且允许对分区上锁,而不是之前的全表上锁。
指定分区列
和Compression一样,在SQL Server 2008中也提供了分区的向导界面。在企业管理器中,需要分区的表上右键选择Storage-》Create Partition:
这里会列出该表所有的字段,包括字段类型、长度、精度及小数位数的信息,可以选择其中的任意一一列作为分区列(Patitioning Column),不仅仅是数字或者日期类型,即使是字符串类型的列,也可以按照字母顺序进行分区。而以下类型的列不可用于分区:text、ntext、image、xml、timestamp、varchar(max)、nvarchar(max)、varbinary(max)、别名、hierarchyid、空间索引或 CLR 用户定义的数据类型。此外,如果使用计算列作为分区列,则必须将该列设为持久化列(Persisit)。
在列表下方,提供了两个选项:
-
分配到可用分区表:
这要求在同一数据库下有另一张已分好区的表,同时该表的分区列和当前选中的列的类型完全一致。
这样的好处是当两张表在查询中有关联时,并且其关联列就是分区列时,使用同样的分区策略会更有效率。 -
将非唯一索引和唯一索引的存储空间调整为与索引分区列一致:
这样会将表中的所有索引也一同分区,实现“对齐”。这是一个重要而麻烦的选项,具体需求请参阅MSDN(已分区索引的特殊指导原则)。
这样的好处是表和索引的分区一致,一方面查询时利用索引更为高效,而且在下文提到的移入移出分区也会更为高效。
注意:这里建议使用聚集索引列作为分区列。一方面索引结构本身就应与查询相关,那么分区列与索引一致会保证查询的最大效率;另一方面,保证索引对齐而且是聚集索引对齐是保证分区的移入移出操作顺畅的前提,否则可能会出现无法移入移出的情况,而分区的移入移出又是管理大数据的重要策略——滑动窗口(SlideWindow)策略的基础操作。
分区函数与分区方案
选好分区列后,如果没有应用“分配到可用分区表”选项,接下来则会进入选择\创建分区函数以及分区方案的界面。其中分区函数会指定分区边界,而分区方案则规划了每个分区所存储的文件组。
向导操作界面如下:
其中Left boundary说明每个分区的边界值被包含在边界值左侧的分区中,也就是每个分区内的数据约束是,相应的,Right boundary则说明每个分区的边界值被包含在边界值右侧的分区中,每个分区内的数据约束是。
在下方的列表中,列出了当前分区方案下现有的分区。其中文件组(Filegroup)指定了每个分区存放的位置,如果将分区放置于位于不同磁盘中的不同文件组中,由于不同磁盘的读写互不干扰,这将提高分区表并行处理的效率。一般情况下,将所有分区放置在同一个文件组是比较稳妥的做法。关于文件组的展开阅读可以参阅:SQL Server Filegroups。
注意,在这里最后一个分区是没有指定边界的,用于保存所有>(Left Boundary)或>=(Right boundary)最后一个分区边界的数据。
如果选择时间类型的字段作为分区列,可以通过Set按钮实现按条件分组:
这样可以很方便得通过设置起止时间将表按照指定时间段自动分区,但之后依然需要手动指定每个分区的文件组。
制定好分区方案之后可以通过Estimate sotrage预估每个分区的行数、空间占用情况,不过除非需要以占用空间或行数来规划你的分区策略,一般不建议在这里进行预估,因为如果对空表来说,预估的结果当然都是0,而如果表中已经包含大量数据,预估则会花费比较长的时间。
创建分区
通过以上设置,分区已经基本完毕,在向导的最后,可以选择是创建脚本还是立即执行分区操作。
我们可以查看在不同情况下创建分区的脚本的情况:
1.在表没有索引的情况下:
<span>BEGIN TRANSACTION CREATE PARTITION FUNCTION </span>[TestFunction]<span>(</span><span>datetime</span><span>) </span><span>AS RANGE </span><span>LEFT </span><span>FOR VALUES </span><span>(</span><span>N'2010-01-01T00:00:00'</span><span>, </span><span>N'2010-02-01T00:00:00'</span><span>, <br></span><span>N'2010-03-01T00:00:00'</span><span>, </span><span>N'2010-04-01T00:00:00'</span><span>, </span><span>N'2010-05-01T00:00:00'</span><span>, </span><span>N'2010-06-01T00:00:00'</span><span>) </span><span>CREATE PARTITION </span>SCHEME [TestScheme] <span>AS PARTITION </span>[TestFunction] <span>TO </span><span>(</span>[PRIMARY]<span>, </span>[PRIMARY]<span>, </span>[PRIMARY]<span>, <br></span>[PRIMARY]<span>, </span>[PRIMARY]<span>, </span>[PRIMARY]<span>, </span>[PRIMARY]<span>) </span><span>CREATE CLUSTERED INDEX </span>[ClusteredIndex_on_TestScheme_634025264502439124] <span>ON </span>[dbo]<span>.</span>[Account] <span>( </span>[birthday] <span>)</span><span>WITH </span><span>(</span><span>SORT_IN_TEMPDB </span><span>= </span><span>OFF</span><span>, </span><span>IGNORE_DUP_KEY </span><span>= </span><span>OFF</span><span>, </span><span>DROP_EXISTING </span><span>= </span><span>OFF</span><span>, </span><span>ONLINE </span><span>= </span><span>OFF</span><span>) </span><span>ON </span>[TestScheme]<span>(</span>[birthday]<span>) </span><span>DROP INDEX </span>[ClusteredIndex_on_TestScheme_634025264502439124] <span>ON </span>[dbo]<span>.</span>[Account] <span>WITH </span><span>( </span><span>ONLINE </span><span>= </span><span>OFF </span><span>) </span><span>COMMIT TRANSACTION</span>
这里先创建Partition Function以及Partition Scheme,之后在分区列上创建聚集索引并按照分区方案分区,最后删除了这一索引。
2.在表有索引的情况下:
如果原先没有聚集索引:
<span>CREATE CLUSTERED INDEX </span>[ClusteredIndex_on_TestScheme_634025229911990663] <span>ON </span>[dbo]<span>.</span>[Account] <span>( </span>[birthday] <span>)</span><span>WITH </span><span>(</span><span>SORT_IN_TEMPDB </span><span>= </span><span>OFF</span><span>, </span><span>IGNORE_DUP_KEY </span><span>= </span><span>OFF</span><span>, </span><span>DROP_EXISTING </span><span>= </span><span>OFF</span><span>, </span><span>ONLINE </span><span>= </span><span>OFF</span><span>) </span><span>ON </span>[TestScheme]<span>(</span>[birthday]<span>) </span><span>DROP INDEX </span>[ClusteredIndex_on_TestScheme_634025229911990663] <span>ON </span>[dbo]<span>.</span>[Account] <span>WITH </span><span>( </span><span>ONLINE </span><span>= </span><span>OFF </span><span>) </span>
这和没有索引的情况一样,如果表原先存在聚集索引,则脚本变为:
<span>CREATE CLUSTERED INDEX </span>[IX_id] <span>ON </span>[dbo]<span>.</span>[Account] <span>( </span>[id] <span>ASC </span><span>)</span><span>WITH </span><span>(</span><span>PAD_INDEX </span><span>= </span><span>OFF</span><span>, </span><span>STATISTICS_NORECOMPUTE </span><span>= </span><span>OFF</span><span>, </span><span>SORT_IN_TEMPDB </span><span>= </span><span>OFF</span><span>, </span><span>IGNORE_DUP_KEY </span><span>= </span><span>OFF</span><span>, </span><span>DROP_EXISTING </span><span>= </span><span>ON</span><span>, <br></span><span>ONLINE </span><span>= </span><span>OFF</span><span>, </span><span>ALLOW_ROW_LOCKS </span><span>= </span><span>ON</span><span>, </span><span>ALLOW_PAGE_LOCKS </span><span>= </span><span>ON</span><span>) </span><span>ON </span>[TestScheme]<span>(</span>[birthday]<span>)</span>
可以看到原有的聚集索引(IX_id)在分区方案上被重建了。
如果选择了“对齐索引”选项,则会对所有索引都应用分区:
<span>CREATE CLUSTERED INDEX </span>[IX_id] <span>ON </span>[dbo]<span>.</span>[Account] <span>( </span>[id] <span>ASC </span><span>)</span><span>WITH </span><span>(</span><span>PAD_INDEX </span><span>= </span><span>OFF</span><span>, </span><span>STATISTICS_NORECOMPUTE </span><span>= </span><span>OFF</span><span>, </span><span>SORT_IN_TEMPDB </span><span>= </span><span>OFF</span><span>, </span><span>IGNORE_DUP_KEY </span><span>= </span><span>OFF</span><span>, </span><span>DROP_EXISTING </span><span>= </span><span>ON</span><span>, <br></span><span>ONLINE </span><span>= </span><span>OFF</span><span>, </span><span>ALLOW_ROW_LOCKS </span><span>= </span><span>ON</span><span>, </span><span>ALLOW_PAGE_LOCKS </span><span>= </span><span>ON</span><span>) </span><span>ON </span>[TestScheme]<span>(</span>[birthday]<span>) </span><span>CREATE NONCLUSTERED INDEX </span>[UIX_birthday] <span>ON </span>[dbo]<span>.</span>[Account] <span>( </span>[birthday] <span>ASC </span><span>)</span><span>WITH </span><span>(</span><span>PAD_INDEX </span><span>= </span><span>OFF</span><span>, </span><span>STATISTICS_NORECOMPUTE </span><span>= </span><span>OFF</span><span>, </span><span>SORT_IN_TEMPDB </span><span>= </span><span>OFF</span><span>, </span><span>IGNORE_DUP_KEY </span><span>= </span><span>OFF</span><span>, </span><span>DROP_EXISTING </span><span>= </span><span>ON</span><span>, <br></span><span>ONLINE </span><span>= </span><span>OFF</span><span>, </span><span>ALLOW_ROW_LOCKS </span><span>= </span><span>ON</span><span>, </span><span>ALLOW_PAGE_LOCKS </span><span>= </span><span>ON</span><span>) </span><span>ON </span>[TestScheme]<span>(</span>[birthday]<span>) </span><span>CREATE NONCLUSTERED INDEX </span>[UIX_name] <span>ON </span>[dbo]<span>.</span>[Account] <span>( </span>[name] <span>ASC </span><span>)</span><span>WITH </span><span>(</span><span>PAD_INDEX </span><span>= </span><span>OFF</span><span>, </span><span>STATISTICS_NORECOMPUTE </span><span>= </span><span>OFF</span><span>, </span><span>SORT_IN_TEMPDB </span><span>= </span><span>OFF</span><span>, </span><span>IGNORE_DUP_KEY </span><span>= </span><span>OFF</span><span>, </span><span>DROP_EXISTING </span><span>= </span><span>ON</span><span>, <br></span><span>ONLINE </span><span>= </span><span>OFF</span><span>, </span><span>ALLOW_ROW_LOCKS </span><span>= </span><span>ON</span><span>, </span><span>ALLOW_PAGE_LOCKS </span><span>= </span><span>ON</span><span>)</span>
这里不仅对聚集索引IX_id进行了分区,也对非聚集索引UIX_name和UIX_birthday进行了分区。
注意事项
- 对一张表分好区后不可以进行再次分区,同时也没有直接取消表分区的方法。
- 如果要查看已分区表的分区状态以及每个分区中的行数和占用空间,可以通过Storage-》Management Compression查看。同时可以在这里为每个分区指定压缩方式。
- 如果分区表索引没有对齐,则不可以对该表进行切入切出(Switch in/out)操作,同样也不能执行滑动窗口操作。
- 分区实际上是在每个分区表都添加了约束,相应的插入操作的性能也会受到影响。
- 即使进行了分区,如果查询的条件字段和分区列并没有关联,性能也未必会得到提升。

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas











Perbandingan prestasi kaedah membalik nilai kunci tatasusunan PHP menunjukkan bahawa fungsi array_flip() berprestasi lebih baik daripada gelung for dalam tatasusunan besar (lebih daripada 1 juta elemen) dan mengambil masa yang lebih singkat. Kaedah gelung untuk membalikkan nilai kunci secara manual mengambil masa yang agak lama.

Perbandingan prestasi rangka kerja Java yang berbeza: Pemprosesan permintaan REST API: Vert.x adalah yang terbaik, dengan kadar permintaan 2 kali SpringBoot dan 3 kali Dropwizard. Pertanyaan pangkalan data: HibernateORM SpringBoot adalah lebih baik daripada Vert.x dan ORM Dropwizard. Operasi caching: Pelanggan Hazelcast Vert.x lebih unggul daripada mekanisme caching SpringBoot dan Dropwizard. Rangka kerja yang sesuai: Pilih mengikut keperluan aplikasi Vert.x sesuai untuk perkhidmatan web berprestasi tinggi, SpringBoot sesuai untuk aplikasi intensif data, dan Dropwizard sesuai untuk seni bina perkhidmatan mikro.

Kerumitan masa mengukur masa pelaksanaan algoritma berbanding saiz input. Petua untuk mengurangkan kerumitan masa program C++ termasuk: memilih bekas yang sesuai (seperti vektor, senarai) untuk mengoptimumkan storan dan pengurusan data. Gunakan algoritma yang cekap seperti isihan pantas untuk mengurangkan masa pengiraan. Hapuskan berbilang operasi untuk mengurangkan pengiraan berganda. Gunakan cawangan bersyarat untuk mengelakkan pengiraan yang tidak perlu. Optimumkan carian linear dengan menggunakan algoritma yang lebih pantas seperti carian binari.

Teknik berkesan untuk mengoptimumkan prestasi berbilang benang C++ termasuk mengehadkan bilangan utas untuk mengelakkan perbalahan sumber. Gunakan kunci mutex ringan untuk mengurangkan perbalahan. Optimumkan skop kunci dan minimumkan masa menunggu. Gunakan struktur data tanpa kunci untuk menambah baik keselarasan. Elakkan sibuk menunggu dan maklumkan urutan ketersediaan sumber melalui acara.

Dalam PHP, penukaran tatasusunan kepada objek akan memberi kesan pada prestasi, yang dipengaruhi terutamanya oleh faktor seperti saiz tatasusunan, kerumitan dan kelas objek. Untuk mengoptimumkan prestasi, pertimbangkan untuk menggunakan iterator tersuai, mengelakkan penukaran yang tidak perlu, tatasusunan penukaran kelompok dan teknik lain.

Cara terbaik untuk menjana nombor rawak dalam Go bergantung pada tahap keselamatan yang diperlukan oleh aplikasi anda. Keselamatan rendah: Gunakan pakej matematik/rand untuk menjana nombor pseudo-rawak, sesuai untuk kebanyakan aplikasi. Keselamatan tinggi: Gunakan pakej crypto/rand untuk menjana bait rawak selamat secara kriptografi, sesuai untuk aplikasi yang memerlukan rawak yang lebih kuat.

Mengikut penanda aras, untuk aplikasi kecil dan berprestasi tinggi, Quarkus (permulaan pantas, memori rendah) atau Micronaut (TechEmpower cemerlang) adalah pilihan yang ideal. SpringBoot sesuai untuk aplikasi bertindan penuh yang besar, tetapi mempunyai masa permulaan dan penggunaan memori yang lebih perlahan.

Format URL sambungan Navicat ialah: protocol://username:password@host:port/database names, yang mengandungi maklumat yang diperlukan untuk sambungan, termasuk protokol, nama pengguna, kata laluan, nama hos, port, nama pangkalan data dan pilihan? parameter.
