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)操作,同样也不能执行滑动窗口操作。
- 分区实际上是在每个分区表都添加了约束,相应的插入操作的性能也会受到影响。
- 即使进行了分区,如果查询的条件字段和分区列并没有关联,性能也未必会得到提升。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











PHP の配列キー値の反転メソッドのパフォーマンスを比較すると、array_flip() 関数は、大規模な配列 (100 万要素以上) では for ループよりもパフォーマンスが良く、所要時間が短いことがわかります。キー値を手動で反転する for ループ方式は、比較的長い時間がかかります。

さまざまな Java フレームワークのパフォーマンス比較: REST API リクエスト処理: Vert.x が最高で、リクエスト レートは SpringBoot の 2 倍、Dropwizard の 3 倍です。データベース クエリ: SpringBoot の HibernateORM は Vert.x や Dropwizard の ORM よりも優れています。キャッシュ操作: Vert.x の Hazelcast クライアントは、SpringBoot や Dropwizard のキャッシュ メカニズムよりも優れています。適切なフレームワーク: アプリケーションの要件に応じて選択します。Vert.x は高パフォーマンスの Web サービスに適しており、SpringBoot はデータ集約型のアプリケーションに適しており、Dropwizard はマイクロサービス アーキテクチャに適しています。

時間計算量は、入力のサイズに対するアルゴリズムの実行時間を測定します。 C++ プログラムの時間の複雑さを軽減するためのヒントには、適切なコンテナー (ベクター、リストなど) を選択して、データのストレージと管理を最適化することが含まれます。クイックソートなどの効率的なアルゴリズムを利用して計算時間を短縮します。複数の操作を排除して二重カウントを削減します。条件分岐を使用して、不必要な計算を回避します。二分探索などのより高速なアルゴリズムを使用して線形探索を最適化します。

C++ マルチスレッドのパフォーマンスを最適化するための効果的な手法には、リソースの競合を避けるためにスレッドの数を制限することが含まれます。競合を軽減するには、軽量のミューテックス ロックを使用します。ロックの範囲を最適化し、待ち時間を最小限に抑えます。ロックフリーのデータ構造を使用して同時実行性を向上させます。ビジー待機を回避し、イベントを通じてリソースの可用性をスレッドに通知します。

PHP では、配列からオブジェクトへの変換はパフォーマンスに影響を与え、主に配列のサイズ、複雑さ、オブジェクト クラスなどの要因によって影響を受けます。パフォーマンスを最適化するには、カスタム反復子の使用、不必要な変換の回避、配列のバッチ変換などの手法を検討してください。

Go で乱数を生成する最適な方法は、アプリケーションに必要なセキュリティのレベルによって異なります。低セキュリティ: math/rand パッケージを使用して、ほとんどのアプリケーションに適した疑似乱数を生成します。高いセキュリティ: crypto/rand パッケージを使用して、より強力なランダム性を必要とするアプリケーションに適した、暗号的に安全なランダム バイトを生成します。

ベンチマークによると、小規模で高性能なアプリケーションの場合、Quarkus (高速起動、低メモリ) または Micronaut (TechEmpower に優れた) が理想的な選択肢です。 SpringBoot は大規模なフルスタック アプリケーションに適していますが、起動時間とメモリ使用量が若干遅くなります。

Navicat 接続 URL の形式は次のとおりです。protocol://username:password@host:port/database name? パラメータには、プロトコル、ユーザー名、パスワード、ホスト名、ポート、データベース名、オプションなど、接続に必要な情報が含まれます。パラメータ。
