當前位置:首頁 » 編程語言 » sql重建索引的命令是
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql重建索引的命令是

發布時間: 2022-10-01 01:12:56

❶ 如何利用Mysql命令創建,查看,重建和刪除索引

第一步,創建資料庫表t_tree_info,命令如下:
create table t_tree_info(
id int(8),
tno int(4),
tname varchar(20),
tdesc varchar(100)
);
如下圖所示:

第二步,向表裡插入3條數據,插入後查看錶記錄,如下圖所示:

第三步,創建資料庫索引tree_name,命令如下:
create index tree_name on t_tree_info (tname(20));
如下圖所示:

第四步,查看資料庫表索引,利用show命令
show index from t_tree_info;
如下圖所示:

第五步,重建索引,利用repari命令
repair table t_tree_info quick;
如下圖所示:

第六步,索引創建好了,在不使用該索引時,可以刪除
drop index tree_name on t_tree_info;
如下圖所示:

❷ 如何重建SQL索引 要具體的命令

USE TableName
DECLARE @TableName varchar(255)
DECLARE TableCursor CURSOR FOR
SELECT table_name FROM information_schema.tables
WHERE table_type = 'base table'
OPEN TableCursor
FETCH NEXT FROM TableCursor INTO @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
DBCC DBREINDEX(@TableName,' ',90)
FETCH NEXT FROM TableCursor INTO @TableName
END
CLOSE TableCursor
DEALLOCATE TableCursor

❸ sql server如何重建索引到其它文件組

在日常工作中,我們發現很多實施案例中,sql server的資料庫數據與索引在一起。我見過一個客戶的,他的資料庫總共大小才60g,但索引與數據完全混在一起,從管理資料庫的直覺來看,性能方面肯定有問題,所以我建議他們,不管怎麼樣,把索引與資料庫分開,對性能是有好處的!但是sql server的索引,想要通過重建的方式,把數據與索引分開,並不是一件容易的事懷,在使用rebuild時,並不能增加文件組選項。後來研究發現,可以通過以下方式把數據與非聚簇索引分開,具體如下:
set nocount on

declare @index table
(
object_id int,
objectName sysname,
index_id int,
indexName sysname,
fill_factor tinyint,
allow_row_locks bit,
allow_page_locks bit,
is_padded bit,
indexText varchar(max),
indexTextEnd varchar(max)
)

declare @indexColumn table
(
object_id int,
index_id int,
column_id int,
index_column_id int,
max_index_column_id int,
is_descending_key bit,
is_included_column bit,
columnName varchar(255),
indexText varchar(max) null
)

insert into @index
select
i.object_id,
object_name(i.object_id),
i.index_id,
i.name,
fill_factor,
allow_row_locks,
allow_page_locks,
is_padded,
'CREATE NONCLUSTERED INDEX [' + i.name + '] ON [dbo].[' + object_name(i.object_id) + '] ' + char(13),
'WITH (PAD_INDEX = ' +
CASE WHEN is_padded = 1 THEN ' ON ' ELSE ' OFF ' END +
', STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = ON, ONLINE = OFF, ALLOW_ROW_LOCKS = ' +
CASE WHEN allow_row_locks = 1 THEN ' ON ' ELSE ' OFF ' END +
', ALLOW_PAGE_LOCKS = ' +
CASE WHEN allow_page_locks = 1 THEN ' ON ' ELSE ' OFF ' END +
CASE WHEN fill_factor > 0 THEN ', FILLFACTOR = ' + convert(varchar(3), fill_factor) ELSE '' END +
') ON [IndexFG];print('''+i.name+' @ '+object_name(i.object_id)+''')' --+ CHAR(13) + ' GO;'+ CHAR(13) --注意標紅的地方,這是新的文件組的名稱
from sys.indexes i
where i.type = 2 and not exists(select 1 from sys.key_constraints kc where kc.name=i.name)
and objectproperty(i.object_id , 'IsUserTable') = 1
order by object_name(i.object_id), i.name

insert into @indexColumn
select
i.object_id,
i.index_id,
ic.column_id,
ic.index_column_id,
max(ic.index_column_id) over (partition by i.object_id, i.index_id, is_included_column),
is_descending_key,
is_included_column,
'[' + c.name + ']',
null
from @index i
join sys.index_columns ic
on i.object_id = ic.object_id
and i.index_id = ic.index_id
join sys.columns c
on ic.object_id = c.object_id
and ic.column_id = c.column_id
order by i.object_id, i.index_id, ic.index_column_id

declare @fields varchar(max)
declare @object_id int, @index_id int

select @fields = null, @object_id = -1, @index_id = -1

update @indexColumn
set @fields = indexText =
case when object_id = isnull(@object_id, object_id) and index_id = isnull(@index_id, index_id)
then isnull(@fields + ', ', ' ') + columnName + case when is_descending_key = 0 then ' ASC' else ' DESC' end
else columnName + case when is_descending_key = 0 then ' ASC' else ' DESC' end
end,
@object_id = case when object_id <> @object_id
then object_id else @object_id end,
@index_id = case when index_id <> @index_id
then index_id else @index_id end
from @indexColumn
where is_included_column = 0

select @fields = null, @object_id = -1, @index_id = -1

update @indexColumn
set @fields = indexText =
case when object_id = isnull(@object_id, object_id) and index_id = isnull(@index_id, index_id)
then isnull(@fields + ', ', ' ') + columnName
else columnName
end,
@object_id = case when object_id <> @object_id
then object_id else @object_id end,
@index_id = case when index_id <> @index_id
then index_id else @index_id end
from @indexColumn
where is_included_column = 1

update @index
set indexText = i.indexText + '( ' + char(13) + char(9) + ic.indexText + char(13) + ') '
from @index i join @indexColumn ic
on i.object_id = ic.object_id
and i.index_id = ic.index_id
and ic.index_column_id = ic.max_index_column_id
and ic.is_included_column = 0

update @index
set indexText = i.indexText + 'INCLUDE ( ' + char(13) + char(9) + ic.indexText + char(13) + ') '
from @index i join @indexColumn ic
on i.object_id = ic.object_id
and i.index_id = ic.index_id
and ic.index_column_id = ic.max_index_column_id
and ic.is_included_column = 1

update @index
set indexText = indexText + indexTextEnd
from @index

select indexText, objectName, indexName
from @index

最後的查詢結果第一行就是執行的命令!

❹ 在PL-SQL中如何給oracle資料庫重建索引

重建索引有多種方式,如drop and re-create、rebuild、rebuild online等。下面簡單比較這幾種方式異同以及優缺點:
首先建立測試表及數據:
SQL> CREATE TABLE TEST AS SELECT CITYCODE C1 FROM CITIZENINFO2;
Table created
SQL> ALTER TABLE TEST MODIFY C1 NOT NULL;
Table altered
SQL> SELECT COUNT(1) FROM TEST;
COUNT(1)
----------
16000000
一、drop and re-create和rebuild
首先看看正常建立索引時,對表的加鎖情況。
suk@ORACLE9I> @show_sid
SID
----------
14
suk@ORACLE9I> CREATE INDEX IDX_TEST_C1 ON TEST(C1);
索引已創建。
SQL> SELECT OBJECT_NAME,LMODE FROM V$LOCK L,DBA_OBJECTS O WHERE O.OBJECT_ID=L.ID1 AND L.TYPE='TM' AND SID=14;
OBJECT_NAME LMODE
------------------------------ ----------
OBJ$ 3
TEST 4
可見,普通情況下建立索引時,oracle會對基表加share鎖,由於share鎖和 row-X是不兼容的,也就是說,在建立索引期間,無法對基表進行DML操作。
對於刪除重建索引的方法就不介紹了,它與上面的描述是一樣的,下面我們看看用rebuild的方式建立索引有什麼特別。
suk@ORACLE9I> ALTER INDEX IDX_TEST_C1 REBUILD;
索引已更改。
另開一個會話,查詢此時test的加鎖情況:
SQL> SELECT OBJECT_NAME,LMODE FROM V$LOCK L,DBA_OBJECTS O WHERE O.OBJECT_ID=L.ID1 AND L.TYPE='TM' AND SID=14;
OBJECT_NAME LMODE
------------------------------ ----------
TEST 4
可見,rebuild的方式對基表的加鎖方式與CREATE時是一樣的。
另開一個會話,在索引正在rebuild時,執行如下SQL:
suk@ORACLE9I> SET AUTOTRACE TRACE
suk@ORACLE9I> SELECT /*+ INDEX(TEST) */ COUNT(1) FROM TEST WHERE ROWNUM<10;
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=26 Card=1)
1 0 SORT (AGGREGATE)
2 1 COUNT (STOPKEY)
3 2 INDEX (FULL SCAN) OF 'IDX_TEST_C1' (NON-UNIQUE) (Cost=
26 Card=1986621)
可以看到索引在重建時,查詢仍然可以使用舊索引。實際上,oracle在rebuild時,在創建新索引過程中,並不會刪除舊索引,直到新索引rebuild成功。
從這點可以知道rebuild比刪除重建的一個好處是不會影響原有的SQL查詢,但也正由於此,用rebuild方式建立索引需要相應表空間的空閑空間是刪除重建方式的2倍。
重建索引有多種方式,如drop and re-create、rebuild、rebuild online等。下面簡單比較這幾種方式異同以及優缺點:
相關文章:
oracle重建索引(一)
二、rebuild 和rebuild online
首先我們跟蹤一下rebuild online的過程。
另開一個會話查看鎖的信息:
SQL> SELECT OBJECT_NAME,LMODE FROM V$LOCK L,DBA_OBJECTS O WHERE O.OBJECT_ID=L.ID1 AND L.TYPE='TM' AND SID=14;
OBJECT_NAME LMODE
------------------------------ ----------
SYS_JOURNAL_10499 4
TEST 2
SQL> INSERT INTO TEST VALUES(11);
1 row inserted
SQL> COMMIT;
Commit complete
可以看到,在rebuild online期間,oracle對基表加的是RS所,此時我們可以對基表進行DML操作。但奇怪的話在相同的session中有一個SYS_JOURNAL_10499表被加SHARE鎖,這個表是干什麼用的呢?
我們看看trace文件,有這樣的信息:
create table "SUK"."SYS_JOURNAL_10499" (C0 NUMBER(6,0), opcode char(1),
partno number, rid rowid, primary key( C0 , rid )) organization index
TABLESPACE "TEST"
CREATE UNIQUE INDEX "SUK"."SYS_IOT_TOP_10605" on
"SUK"."SYS_JOURNAL_10499"("C0","RID") INDEX ONLY TOPLEVEL TABLESPACE "TEST"
NOPARALLEL
drop table "SUK"."SYS_JOURNAL_10499"
我們在查查10499是什麼東西:
SQL> SELECT OBJECT_NAME,OBJECT_TYPE FROM DBA_OBJECTS WHERE OBJECT_ID=10499;
OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------
IDX_TEST_C1 INDEX
從這些信息可以推測:表SYS_JOURNAL_10499就是實現在重建索引時不阻塞DML操作而設計的,它存儲的是在索引重建期間發生在基表的數據變化。可以推測,CREATE INDEX .... ONLINE應該也有一張類似的表。
實際上,oracle之所以在創建索引時鎖表阻止DML操作就是為了防止不能索引新變化的數據,在online方式重建時,有了臨時表SYS_JOURNAL_XXXX,oracle就可以放心大膽地讓用戶操作了,因為所有重建索引期間的數據變化信息都會保留在SYS_JOURNAL_XXX表中,當索引重建完後再加上SYS_JOURNAL_XXX記錄的數據,就不會漏索引數據了。(XXX是被重建的索引對應的OBJECT_ID)
導讀:
重建索引有多種方式,如drop and re-create、rebuild、rebuild online等。下面簡單比較這幾種方式異同以及優缺點:
相關文章:
oracle重建索引(一)
oracle重建索引(二)
三、rebuild和rebuild online的數據源
網上一直有這樣一個說法:重建索引是以原索引作為數據源的。那麼,這種說法是否准確呢?我們做實驗來驗證一下:
suk@ORACLE9I> COL SEGMENT_NAME FORMAT A30
--首先看看錶和索引的大小
suk@ORACLE9I> SELECT SEGMENT_NAME,BYTES FROM USER_SEGMENTS WHERE SEGMENT_NAME IN ('TEST','IDX_TEST_C1');
SEGMENT_NAME BYTES
------------------------------ ----------
TEST 201326592
IDX_TEST_C1 293601280
suk@ORACLE9I> EXPLAIN PLAN FOR ALTER INDEX IDX_TEST_C1 REBUILD;
已解釋。
suk@ORACLE9I> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-----------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | | | |
| 1 | INDEX BUILD NON UNIQUE| IDX_TEST_C1 | | | |
| 2 | SORT CREATE INDEX | | | | |
| 3 | TABLE ACCESS FULL | TEST | | | |
-----------------------------------------------------------------------
Note: rule based optimization
已選擇11行。
--從執行計劃可以看出,當索引比表大時,rebuild索引用的數據源是基表。
suk@ORACLE9I> EXPLAIN PLAN FOR ALTER INDEX IDX_TEST_C1 REBUILD ONLINE;
已解釋。
suk@ORACLE9I> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-----------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | | | |
| 1 | INDEX BUILD NON UNIQUE| IDX_TEST_C1 | | | |
| 2 | SORT CREATE INDEX | | | | |
| 3 | TABLE ACCESS FULL | TEST | | | |
-----------------------------------------------------------------------
Note: rule based optimization
已選擇11行。
--從執行計劃可以看出,當索引比表大時,rebuild online索引用的數據源是基表。
--我們為TEST添加一列,使得表比索引大
suk@ORACLE9I> ALTER TABLE TEST ADD(C2 CHAR(30) DEFAULT '1');
表已更改。
suk@ORACLE9I> SELECT SEGMENT_NAME,BYTES FROM USER_SEGMENTS WHERE SEGMENT_NAME IN ('TEST','IDX_TEST_C
1');
SEGMENT_NAME BYTES
------------------------------ ----------
TEST 1476395008
IDX_TEST_C1 293601280
suk@ORACLE9I> EXPLAIN PLAN FOR ALTER INDEX IDX_TEST_C1 REBUILD;
已解釋。
suk@ORACLE9I> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-----------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | | | |
| 1 | INDEX BUILD NON UNIQUE| IDX_TEST_C1 | | | |
| 2 | SORT CREATE INDEX | | | | |
| 3 | INDEX FAST FULL SCAN| IDX_TEST_C1 | | | |
-----------------------------------------------------------------------
Note: rule based optimization
已選擇11行。
--從執行計劃可以看出,當表比索引大時,執行計劃已經改變,rebuild索引是以索引作為數據源的。
suk@ORACLE9I> EXPLAIN PLAN FOR ALTER INDEX IDX_TEST_C1 REBUILD ONLINE;
已解釋。
suk@ORACLE9I> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-----------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | | | |
| 1 | INDEX BUILD NON UNIQUE| IDX_TEST_C1 | | | |
| 2 | SORT CREATE INDEX | | | | |
| 3 | TABLE ACCESS FULL | TEST | | | |
-----------------------------------------------------------------------
Note: rule based optimization
已選擇11行。
--從執行計劃可以看出,當表比索引大時,rebuild online仍然以基表作為數據源。
rebuild模式下,因為表數據不會產生變化,oracle主要考慮性能問題,把更快掃描完成的段作為數據源。在上面的例子中,我們並沒有對表進行分析,故oracle應該根據數據段的大小來決定那個作為數據源的。一般索引欄位比較多,或者對索引欄位的DML操作較多,可能會導致索引比表大,這時oracle就會使用基表作為新索引的數據源進行rebuild了。
而在rebuild online模式下,因為允許DML操作,而表數據變化的同時索引也會跟著變化,為了索引與基表數據的一致性,比如採用基表數據作為數據源,而不能用原索引數據作為數據源。
我們用反證法證明不能用原索引作為新索引的數據源。
例如:
T1發出rebuild online命令
T2刪除某條數據,刪數據的同時,oracle會自動維護了舊索引
T3掃描經過T2數據所在索引節點
T4插入一條記錄,新記錄對應的索引節點剛好重用了T2刪除的數據對應的索引節點空間
如果是這樣的話,新建的索引將不包含T4插入的記錄的信息。所以,rebuild online情況下新索引的數據源不能是原索引。
rebuild online情況下,如果非用原索引作為新索引的數據源的話,用中間表記錄索引變化的方法應該是可以實現的,但由於數據變化會同時引起索引變化的特定決定了這種方法將異常復雜及效率底下,所以oracle不考慮舊索引作為新索引的數據源是有道理的。
結論:
1、rebuild會阻塞對基表的DML操作,但不會影響rebuild期間查詢對原有索引的使用。
2、rebuild的數據源可能是基表,也可能是原索引。取決於基表和原索引的大小,那個小,rebuild時就會用那個作為數據源。這也說明了網上盛傳的rebuild以原索引作為資料庫的說法是不完全正確的。
3、rebuild online運行用戶在索引重建期間執行DML操作。
4、rebuild online的數據源是基表

❺ sql server 重新生成索引可以減小資料庫空間嗎

sql server 重新生成索引可以減小資料庫空間。
理由分析:
一、重新生成索引:
1、命令: ALTER INDEX 索引名 on 表名 REBUILD
2、解析:重新生成索引將刪除該索引並創建一個新索引。此過程中將刪除碎片,通過使用指定的或現有的填充因子設置壓縮頁來回收磁碟空間,並在連續頁中對索引行重新排序(根據需要分配新頁)。這樣可以減少獲取所請求數據所需的頁讀取數,從而提高磁碟性能。

二、重新組織索引:
1、命令:ALTER INDEX 索引名 on 表名 reorganize
2、解析: 重新組織索引是通過對葉頁進行物理重新排序,使其與葉節點的邏輯順序(從左到右)相匹配,從而對表或視圖的聚集索引和非聚集索引的葉級別進行碎片整理。使頁有序可以提高索引掃描的性能。索引在分配給它的現有頁內重新組織,而不會分配新頁。如果索引跨多個文件,將一次重新組織一個文件,不會在文件之間遷移頁。
重新組織還會壓縮索引頁。如果還有可用的磁碟空間,將刪除此壓縮過程中生成的所有空頁。壓縮基於 sys.indexes 目錄視圖中的填充因子值。
重新組織進程使用最少的系統資源。而且,重新組織是自動聯機執行的。該進程不持有長期阻塞鎖,所以不會阻止運行查詢或更新。
索引碎片不太多時,可以重新組織索引。

❻ sql server 怎麼建立索引

創建索引:
(1)在SQL Server Management Studio中,選擇並右擊要創建索引的表,從彈出菜單中選擇「設計」,打開表設計器。右鍵單擊表設計器,從彈出菜單中選擇「索引/鍵」命令,打開「索引/鍵」對話框。對話框中列出了已經存在的索引,如下圖所示。
(2)單擊「添加」按鈕。在「選定的主/唯一鍵或索引」框顯示系統分配給新索引的名稱。
(3)在「列」屬性下選擇要創建索引的列。可以選擇多達16列。為獲得最佳性能,最好只選擇一列或兩列。對所選的每一列,可指出索引是按升序還是降序組織列值。
(4)如果要創建唯一索引,則在「是唯一的」屬性中選擇「是」。
(5)設置完成後,單擊「確定」按鈕。
(6)當保存表時,索引即創建在資料庫中。
使用CREATE INDEX語句創建索引:
復制內容到剪貼板
代碼:
CREATE[ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX索引名
ON {表名|視圖名} (列名[ ASC | DESC ] [ ,...n ] )

例:
在資料庫HrSystem中為表Employees創建基於IDCard列的唯一索引IX_Employees,可以使用以下命令:
復制內容到剪貼板
代碼:
USE HrSystem
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_Employees]ONdbo.Employees(IdCard)
GO

例:
為表Employees創建基於列IDCard的唯一、聚集索引IX_Employees1,可以使用以下命令:
復制內容到剪貼板
代碼:
USE HrSystem
GO
CREATE UNIQUE CLUSTERED INDEX [IX_Employees1] ON [dbo].[Employees](IdCard)
GO

需要注意的是,在一個表中只允許存在一個聚集索引。因此,如果表Employees中已經存在一個聚集索引,則執行上面的語句時將會提示下面的錯誤信息。
消息1902,級別16,狀態3,第1行
無法對表'dbo.Employees'創建多個聚集索引。請在創建新聚集索引前刪除現有的聚集索引'PK__Employee__263E2DD300551192'。 例:
對表Employees的列Emp_name按照降序創建索引,可以使用以下命令:
復制內容到剪貼板
代碼:
USE HrSystem
GO
CREATENONCLUSTERED INDEX [IX_Employees2] ON [dbo].[Employees]
(
[Emp_name] DESC
)
GO

在CREATE INDEX語句中使用INCLUDE子句,可以在創建索引時定義包含的非鍵列,其語法結構如下:
復制內容到剪貼板
代碼:
CREATENONCLUSTERED INDEX 索引名
ON { 表名| 視圖名 } ( 列名 [ ASC | DESC ] [ ,...n ] )
INCLUDE (<列名1>, <列名2>, [,… n])

例: 在表Employees上創建非聚集索引IX_Wage,索引中的鍵列為Wage,非鍵列為Emp_name、Sex和Title,具體語句如下:
復制內容到剪貼板
代碼:
USEHrSystem
GO
CREATENONCLUSTERED INDEX IX_Wage
ON Employees ( Wage )
INCLUDE (Emp_name, Sex, Title)
GO

例: 在創建索引IX_Wage後,當表Employees中的數據量比較大時,執行下面的SELECT語句將會明顯地改進查詢效率。
復制內容到剪貼板
代碼:
USEHrSystem
GO
SELECTEmp_name, Sex, Title, Wage
FROMEmployees
WHEREWage BETWEEN 1000 AND 3000
GO

❼ sql server2008 相隔10天自動刪除索引,然後再重新創建。(高手速來。懸賞大大滴)

思路:
1、創建存儲過程,內容是刪除存儲過程,並重建索引
2、創建作業,然後作業內容是調用上面的存儲過程(切記,執行此存儲過程的用戶一定要有許可權,最好是該資料庫的dbowen),然後設置該作業自動執行的周期
3、恭喜你以後省事了!

❽ SQL中如何重建一張表的索引

SELECT
tab.name AS [表名],
idx.name AS [索引名稱],
col.name AS [列名]
FROM
sys.indexes idx
JOIN sys.index_columns idxCol
ON (idx.object_id = idxCol.object_id
AND idx.index_id = idxCol.index_id
)
JOIN sys.tables tab
ON (idx.object_id = tab.object_id)
JOIN sys.columns col
ON (idx.object_id = col.object_id
AND idxCol.column_id = col.column_id);