優化SQLServer--表和索引的分割槽(二)
簡介
之前一篇簡單的介紹了語法和一些基本的概念,隔了一段時間,覺得有必要細緻的通過例項來總結一下這部分內容。如之前所說,分割槽就是講大型的物件(表)分成更小的塊來管理,基本單位是行。這也就產生了很大優勢, 比如在資料庫維護備份還原操作的時候,比如在大量使用者訪問能導致死鎖的時候等等。
接下來我們通過大量例項從分割槽到展示分割槽的效果以及一些實際案例來提高對這部分知識的理解。
--****************** --1.建立分割槽函式 --****************** --Create the partition function: dailyPF DECLARE @StartDay DATE=DATEADD(dd,-3,CAST(SYSDATETIME() AS DATE)); CREATE PARTITION FUNCTION DailyPF (DATETIME2(0)) AS RANGE RIGHT FOR VALUES (@StartDay, DATEADD(dd,1,@StartDay), DATEADD(dd,2,@StartDay), DATEADD(dd,3,@StartDay), DATEADD(dd,4,@StartDay) ); GO |
範圍分割槽函式指定範圍的邊界,left和right關鍵字指定當資料庫引擎按照剩餘從左到右對區間值進行排序是,邊界值屬於那一邊,預設為left。分割槽範圍不能有間隔。
--****************** --2. 建立檔案組 --****************** ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG1 GO ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG2 GO ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG3 GO ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG4 GO ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG5 GO ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG6 GO |
這裡我們建立6個檔案組,同時也可以為檔案組建立檔案,
接下來我為檔案組建立分割槽方案:
--****************** --3. 建立分割槽架構 --****************** -- CREATE PARTITION SCHEME DailyPS AS PARTITION DailyPF TO (DailyFG1, DailyFG2, DailyFG3, DailyFG4, DailyFG5, DailyFG6); --****************** --4. 在分割槽架構上建表 --****************** if OBJECT_ID('OrdersDaily','U') is null CREATE TABLE OrdersDaily ( OrderDate DATETIME2(0) NOT NULL, OrderId int IDENTITY NOT NULL, OrderName nvarchar(256) NOT NULL ) on DailyPS(OrderDate) GO |
這裡我們將分割槽函式對映到單個檔案組裡面,呼叫我們之前建立的分割槽函式即可。然後接著建立表在分割槽檔案上,同時應用分割槽函式在
OrderDate時間上。這裡我們還需要插入一部分測試資料便於觀察,同時建立一個架構便於查詢分割槽
--******************************* --建立架構 --******************************* --Create a schema for "partition helper" objects CREATE SCHEMA [ph] AUTHORIZATION dbo; GO --插入測試資料 INSERT OrdersDaily(OrderDate, OrderName) SELECT DATEADD(ss, t.N, DATEADD(dd,-3,CAST(CAST(SYSDATETIME() AS DATE) AS DATETIME2(0)))) AS OrderDate, CASE WHEN t.N % 3 = 0 THEN 'Robot' WHEN t.N % 4 = 0 THEN 'Badger' ELSE 'Pen' END AS OrderName FROM ph.tally AS t--tally是一個1到10萬自增長的表,只有一個欄位 N WHERE N < = 1000; INSERT OrdersDaily(OrderDate, OrderName) SELECT DATEADD(ss, t.N, DATEADD(dd,-2,CAST(CAST(SYSDATETIME() AS DATE) AS DATETIME2(0)))) AS OrderDate, CASE WHEN t.N % 3 = 0 THEN 'Flying Monkey' WHEN t.N % 4 = 0 THEN 'Junebug' ELSE 'Pen' END AS OrderName FROM ph.tally AS t WHERE N < = 2000; INSERT OrdersDaily(OrderDate, OrderName) SELECT DATEADD(ss, t.N, DATEADD(dd,-1,CAST(CAST(SYSDATETIME() AS DATE) AS DATETIME2(0)))) AS OrderDate, CASE WHEN t.N % 2 = 0 THEN 'Turtle' WHEN t.N % 5 = 0 THEN 'Eraser' ELSE 'Pen' END AS OrderName FROM ph.tally AS t WHERE N < = 3000; INSERT OrdersDaily(OrderDate, OrderName) SELECT DATEADD(ss, t.N, CAST(CAST(SYSDATETIME() AS DATE) AS DATETIME2(0))) AS OrderDate, CASE WHEN t.N % 3 = 0 THEN 'Lasso' WHEN t.N % 2 = 0 THEN 'Cattle Prod' ELSE 'Pen' END AS OrderName FROM ph.tally AS t WHERE N < = 4000; GO 隨即在建立相關的索引 --****************** --7. 建立索引 --****************** --新增聚集索引 ALTER TABLE OrdersDaily ADD CONSTRAINT PKOrdersDaily PRIMARY KEY CLUSTERED(OrderDate,OrderId) GO --對齊索引 -- CREATE NONCLUSTERED INDEX NCOrderIdOrdersDaily ON OrdersDaily(OrderId) GO --非對齊索引 CREATE NONCLUSTERED INDEX NCOrderNameOrdersDailyNonAligned ON OrdersDaily(OrderName) ON [PRIMARY] GO |
此時建立分割槽檔案資料等條件後,我們可以看一下相應的檔案及資料的情況,可以同過如下DMV來檢視
SELECT SCHEMA_NAME(so.schema_id) AS schema_name , OBJECT_NAME(p.object_id) AS object_name , p.partition_number , p.data_compression_desc , dbps.row_count , dbps.reserved_page_count * 8 / 1024. AS reserved_mb , si.index_id , CASE WHEN si.index_id = 0 THEN '(heap!)' ELSE si.name END AS index_name , si.is_unique , si.data_space_id , mappedto.name AS mapped_to_name , mappedto.type_desc AS mapped_to_type_desc , partitionds.name AS partition_filegroup , pf.name AS pf_name , pf.type_desc AS pf_type_desc , pf.fanout AS pf_fanout , pf.boundary_value_on_right , ps.name AS partition_scheme_name , rv.value AS range_value FROM sys.partitions p JOIN sys.objects so ON p.object_id = so.object_id AND so.is_ms_shipped = 0 LEFT JOIN sys.dm_db_partition_stats AS dbps ON p.object_id = dbps.object_id AND p.partition_id = dbps.partition_id JOIN sys.indexes si ON p.object_id = si.object_id AND p.index_id = si.index_id LEFT JOIN sys.data_spaces mappedto ON si.data_space_id = mappedto.data_space_id LEFT JOIN sys.destination_data_spaces dds ON si.data_space_id = dds.partition_scheme_id AND p.partition_number = dds.destination_id LEFT JOIN sys.data_spaces partitionds ON dds.data_space_id = partitionds.data_space_id LEFT JOIN sys.partition_schemes AS ps ON dds.partition_scheme_id = ps.data_space_id LEFT JOIN sys.partition_functions AS pf ON ps.function_id = pf.function_id LEFT JOIN sys.partition_range_values AS rv ON pf.function_id = rv.function_id AND dds.destination_id = CASE pf.boundary_value_on_right WHEN 0 THEN rv.boundary_id ELSE rv.boundary_id + 1 END |
查詢結果如圖:
可以發現按照日期的分佈產生了不同檔案組的資料插入到了不同的檔案裡面和索引裡面了。
接下來我們通過分割槽切換來更好的理解分割槽的意義,首先要建立新的檔案組(DailyF7)來切換分割槽,同時建立一個分割槽表OrdersDailyLoad,並向這個表裡面插入5000條資料建立索引等以上的操作單獨對此表進行一遍重複操作,來實現對新分割槽的新標的對齊。注意5000條資料一定要在指定範圍內,比如使用check約束使資料在11.30-12.1日內的資料。
程式碼:
在切換之前我們一定要禁用或者刪除掉這個分割槽的對其的索引 ALTER INDEX NCOrderNameOrdersDailyNonAligned ON OrdersDaily DISABLE; GO ALTER TABLE OrdersDailyLoad SWITCH TO OrdersDaily PARTITION 6; GO
如圖,分割槽切換後文件組6中變為了5000條資料,而7中變為了空。
如果需要切換回來執行
ALTER TABLE PARTITION 6 SWITCH TO OrdersDaily OrdersDailyLoad ; GO
如果需要合併分割槽
ALTER PARTITION FUNCTION DailyPF () MERGE RANGE (‘2015-11-27 00:00:00.000’)
結果:此界點兩個分割槽將合併為一個
總結:
通過以上程式碼和例項的展示,我們能瞭解如何使用分割槽。同時我們要知道分割槽的意義。但是要知道分割槽也是一把雙刃劍,它可以看做是一個性能選項、管理選項、可擴充套件工具,在提高資料查詢、維護效能的同時也對資料庫的備份還原策略、索引的維護、併發性以及變分割槽鎖等有副作用,所以具體是否選用表分割槽要根據實際情況來判斷,然後推薦一個工具(DataBase Tuning Adcisor)執行工作負載來提供是否分割槽的建議。
相關推薦
優化SQLServer--表和索引的分割槽(二)
簡介 之前一篇簡單的介紹了語法和一些基本的概念,隔了一段時間,覺得有必要細緻的通過例項來總結一下這部分內容。如之前所說,分割槽就是講大型的物件(表)分成更小的塊來管理,基本單位是行。這也就產生了很大優勢, 比如在資料庫維護備份還原操作的時候,比如在大量使用者訪問能導致死鎖的時候等等。 接下來我們通
oracle,查詢分割槽表和非分割槽表,索引對應的表空間sql
SELECT TABLESPACE_NAME FROM DBA_INDEXES WHERE INDEX_NAME = 'BUSTB_TESTRESULT_IDX1';--非分割槽表SELECT S
反射+列舉+freemarker,自動生成實體類,自動建表建索引(二)之建表建索引,註解和DatabaseMetaData 獲取資訊
package com.test.common; import static com.test.common.EntityConfigData.DEFAULTS; import static com.test.common.EntityConfigData.INDEX; import static com.
sqlserver表和庫管理
sqlserver1.1. ql server 2008R2如何存儲數據數據庫在磁盤上是以文件為單位存儲的,由數據文件和事物日誌文件組成。一個數據庫至少應該包含一個數據文件和一個事物日誌文件。數據庫創建在物理介質(磁盤)上的一個或多個文件上,它預先分配了被數據和事物日誌所要適用的物理存儲空間。存儲數據的文件叫
SqlServer表和excel數據批量復制方法
auto 方法 log 技術 exce 右鍵 表數據 數據復制 -a SqlServer表和excel數據批量復制方法 一、SqlServer表數據復制到excel方法: 1.新建查詢,用sql語句把表數據讀出來 2.然後,選擇數據,右鍵“復制”(如果需要表字段名稱,則點擊
堆組織表,索引組織表和索引聚簇表
卸載 對比 影響 partition 重新登錄 一個數 struct 可變 cal --- 堆組織表就不說了,其索引中記錄了記錄所在位置的rowid,查找的時候先找索引,然後再根據索引rowid找到塊中的行數據索引組織表,其行數據以索引形式存放,因此找到索引,就等於找到了行
MySQL管理表和索引
create div sql 查詢 security nbsp data condition mysq MySQL管理表和索引 創建數據庫: CREATE DATABASE|SCHEMA [IF NOT EXISTS] db_name [CHARACTER SET=
將用戶當前表空間中的表和索引遷移到另一個表空間
數據庫對象 遷移 oracle 查看INV用戶的對象的存儲情況select * from dba_segments ds where ds.owner='INV';--default tablespace users創建表空間INVcreate tablespace inv dat
創建表和索引
rds ati name 5.5 myisam 組合 seq pan primary 1、創建表,這裏需要註意,5.5以後默認引擎是InnoDB,5.1及之前是MyIsam mysql> create table student( -> id int(
SqlServer表和EXCEL數據互相復制方法
數據 打開 標題 字段 一行 序號 www font https 一、SqlServer表數據復制到excel 1、新建查詢,用sql語句把表數據讀出來 2、然後,選擇數據,右鍵,復制(也可以點擊連同標題復制),復制到記事本中(不然會亂碼) 3、然後再把記事本的內容復制,在
十八、dbms_repair(用於檢測,修復在表和索引上的損壞數據塊)
所有者 key 掃描 dbm 壞塊 索引 數據 urg 損壞 1、概述 作用:用於檢測,修復在表和索引上的損壞數據塊. 2、包的組成 1)、admin_tables語法:dbms_repair.admin_tables(table_name in varchar2
第2章聚集索引的表和索引
聚集索引 聚集索引指示表中資料的物理順序,根據聚集排序索引鍵。該表只能定義一個聚集索引。假設您想要在具有資料的堆表上建立叢集索引。作為第一步,如圖2-5所示,SQL Server建立了資料的另一個副本,然後根據叢集金鑰的值對其進行排序。資料頁連結在雙鏈接列表中,其中每個頁都包含指向鏈中的下一頁和前一頁的指標
為什麽要將表和索引建立在不同的表空間?
acl 應用 bsp 影響 目的 系統性能 為什麽 之一 rac 上一個隨筆引出的新問題,找到了一個參考: “Oracle強烈建議,任何一個應用程序的庫表至少需要創建兩個表空間,其中之一用於存儲表數據,而另一個用於存儲表索引數據。因為如果將表數據和索引數據放在一起,表數據的
hive 中的二級分割槽表和動態分割槽表
二級分割槽表/管理表: create table emp_part1( empno int, empname string, empjob string, mgrno int, bi
利用DBCC PAGE檢視SQL Server中的表和索引資料
1.DBCC IND跟DBCC PAGE簡介 1.1.DBCC IND命令 DBCC IND ( { 'dbname' | dbid }, { 'objname' | objid }, { nonclustered indid | 1 | 0 | -1 | -
SqlServer表和Excel檔案資料相互複製方法
SqlServer資料表和Excel檔案之間進行資料互動是很常見的,除了資料庫自帶的“匯入資料”和“匯出資料”功能可以實現兩者之間的資料互動外,還可以直接通過複製的方式進行資料互動。 資料庫UserI
ORACLE分析表和索引的指令碼
-- dbms_output.put_line(rec.segment_name||' '||rec.segment_size||'m '||ceil((dbms_utility.get_time - v_start)/100)||'s'); v_start := dbms_u
mysql查詢優化--臨時表和檔案排序(Using temporary; Using filesort問題解決)
先看一段sql: <span style="font-size:18px;">SELECT * FROM rank_user AS rankUser LEFT JOIN rank_user_level AS userLevel ON rankUser.id
mysql效能調優筆記(二)--查詢優化和索引
一、Mysql執行查詢流程 mysql執行查詢的流程 mysql執行查詢內部路程:1.客服端傳送一條查詢給伺服器
DBCC大全集之(適用版本MS SQLServer 2008 R2)----DBCC CHECKTABLE檢查組成表或索引檢視的所有頁和結構的完整性
如果 DBCC CHECKTABLE 報告了任何錯誤,那麼,我們建議從資料庫備份中還原資料庫,而不是使用某個 REPAIR 選項來執行 REPAIR。如果沒有備份,則執行 REPAIR 也可以更正報告的錯誤。要使用的修復選項在報告的錯誤的末尾處指定。但是,使用 REPAIR_ALLOW_DATA_LOSS