摘要:編者按本文主要介紹使用系統(tǒng)實(shí)體自動(dòng)創(chuàng)建非聚集索引。會(huì)返回缺失索引的細(xì)節(jié)信息。視圖該視圖基于和表,并使用函數(shù)來(lái)計(jì)算缺失的索引名。存儲(chǔ)過(guò)程該存儲(chǔ)過(guò)程基于,并且輸出索引創(chuàng)建語(yǔ)句。
【編者按】 本文主要介紹使用系統(tǒng) SQL 實(shí)體自動(dòng)創(chuàng)建非聚集(non-clustered)索引。作者為意大利軟件工程師 GhostHost(筆名)。
本文系 OneAPM 工程師編譯呈現(xiàn),以下為正文。
引言一直以來(lái),關(guān)于索引的常見(jiàn)問(wèn)題是:判斷哪部分索引對(duì)保證數(shù)據(jù)庫(kù)的良好性能是必需的。在本文中,筆者將提供針對(duì)該問(wèn)題的解決方案。本文用例中的所有代碼都基于名為 dm_db_missing_index_details 的 SQL Server 系統(tǒng)視圖。
背景在開(kāi)始安裝前,進(jìn)一步了解 dm_db_missing_index_details 會(huì)更有益處。
dm_db_missing_index_details 會(huì)返回缺失索引的細(xì)節(jié)信息。在本文中,我們將更關(guān)注以下幾列:
index_handle:它是一個(gè)獨(dú)特的跨服務(wù)器標(biāo)識(shí)符,并且標(biāo)志一個(gè)特定的缺失索引。
equality_columns:包含用于相等謂詞的所有列
inequality_columns:包含用于其他比較的所有列
included columns索引中所包含的查詢必要出現(xiàn)列
statement: 補(bǔ)充完整索引缺失的表名
實(shí)現(xiàn)本系統(tǒng)的實(shí)現(xiàn)基于以下三個(gè)實(shí)體:
一個(gè)可以計(jì)算出待創(chuàng)建索引名稱的簡(jiǎn)單函數(shù)
一個(gè)用于簡(jiǎn)化 dm_db_missing_index_details的用戶視圖
一個(gè)為每個(gè)索引創(chuàng)建聲明的進(jìn)程
筆者選擇將這個(gè)系統(tǒng)分為三段進(jìn)程,但實(shí)際上合并存儲(chǔ)過(guò)程和視圖也是可行的。筆者之所以沒(méi)有選擇后一種做法是因?yàn)橄朐趧?chuàng)建索引之前先從業(yè)務(wù)邏輯檢查一下存在哪些索引。
使用代碼函數(shù) fn_Index_CreateIndexName
在這個(gè)函數(shù)中,有三個(gè)輸入?yún)?shù):
1. @equality_columns 2. @equality_columns 3. @index_handlE
該函數(shù)的目的是為每個(gè)期望創(chuàng)建的索引都創(chuàng)建一個(gè)唯一名稱。
因此,首先拼接@equality_columns和@equality_columns兩個(gè)輸入變量,如果拼接后所得結(jié)果超過(guò)120個(gè)字符,那就截取至第120個(gè)字符。
為什么是120個(gè)字符?
因?yàn)樵赟QL Server中,命名最大長(zhǎng)度為128個(gè)字符。這個(gè)函數(shù)在 @index_handlE 名字結(jié)尾添加字段以便保證唯一的索引名。
CREATE FUNCTION [dbo].[fn_Index_CreateIndexName] (@equality_columns NVARCHAR(4000), _ @Inequality_columns NVARCHAR(4000), @index_handlE INT) RETURNS VARCHAR(128) AS BEGIN DECLARE @IndexName NVARCHAR(255) SET @IndexName = ISNULL(@equality_columns,@Inequality_columns) SET @IndexName = LTRIM(REPLACE(@IndexName,"[","_")) SET @IndexName = RTRIM(REPLACE(@IndexName,"]","_")) SET @IndexName = REPLACE(@IndexName,",","") SET @IndexName = REPLACE(@IndexName,"_ _","_") IF LEN(@IndexName) > 120 BEGIN SET @IndexName = SUBSTRING(@IndexName,0,120) END SET @IndexName = @IndexName + CAST(@index_handlE AS NVARCHAR(15)) RETURN @IndexName END
視圖 vw_Index_MissingIndex
該視圖基于dm_db_missing_index_details和 sys.databases 表,并使用fn_Index_CreateIndexName 函數(shù)來(lái)計(jì)算缺失的索引名。
CREATE VIEW [dbo].[vw_Index_MissingIndex] AS SELECT "[" + d.name + "]" as DBName, [dbo].[fn_Index_CreateIndexName]_ (mid.equality_columns,mid.Inequality_columns,mid.index_handlE) AS ID, REPLACE(mid.equality_columns,","," ASC,") AS equality_columns, REPLACE(mid.Inequality_columns,","," ASC,") AS Inequality_columns, mid.Included_columns, mid.[statement] FROM sys.dm_db_missing_index_details mid INNER JOIN sys.databases d on d.database_id = mid.database_id
存儲(chǔ)過(guò)程 usp_Index_MissingIndexCreationStatements
該存儲(chǔ)過(guò)程基于 vw_Index_MissingIndex,并且輸出索引創(chuàng)建語(yǔ)句。
CREATE PROCEDURE [dbo].[usp_Index_MissingIndexCreationStatements] AS DECLARE @IndexCreationPlaceholder_Start AS NVARCHAR(MAX) DECLARE @IndexCreationPlaceholder_End AS NVARCHAR(MAX) -- PREPARE PLACEHOLDER SET @IndexCreationPlaceholder_Start = "IF NOT EXISTS(SELECT * _ FROM {2}.sys.indexes WHERE [name] = ""IX_{0}"" ) BEGIN CREATE NONCLUSTERED INDEX [IX_{0}] ON {1}" SET @IndexCreationPlaceholder_End = " WITH (PAD_INDEX = OFF, _ STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, _ ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] END;" + char(13) + char(10) -- STATEMENT CREATION SELECT DBName, CASE WHEN NOT mid.equality_columns IS NULL AND NOT mid.Inequality_columns IS NULL THEN REPLACE(REPLACE(REPLACE(@IndexCreationPlaceholder_Start,"{0}", _ mid.ID),"{1}",mid.[statement]),"{2}",mid.DBName) + " ( " + COALESCE(mid.equality_columns,"") + " ASC," + COALESCE(mid.Inequality_columns,"") + " ASC )" + COALESCE("INCLUDE ( " + mid.Included_columns + " ) ","") + @IndexCreationPlaceholder_End WHEN mid.equality_columns IS NULL AND NOT mid.Inequality_columns IS NULL THEN REPLACE(REPLACE(REPLACE(@IndexCreationPlaceholder_Start,_ "{0}", mid.ID),"{1}",mid.[statement]),"{2}",mid.DBName) + " ( " + COALESCE(mid.Inequality_columns,"") + " ASC ) " + COALESCE("INCLUDE ( " + mid.Included_columns + " ) ","") + @IndexCreationPlaceholder_End WHEN NOT mid.equality_columns IS NULL AND mid.Inequality_columns IS NULL THEN REPLACE(REPLACE(REPLACE(@IndexCreationPlaceholder_Start,"{0}", _ mid.ID),"{1}",mid.[statement]),"{2}",mid.DBName) + " ( " + COALESCE(mid.equality_columns,"") + " ASC ) " + COALESCE("INCLUDE ( " + mid.Included_columns + " ) ","") + @IndexCreationPlaceholder_End ELSE NULL END AS Index_Creation_Statement, " DROP INDEX [IX_" + mid.ID + "] ON " + mid.[statement] _ + + char(13) + char(10) AS Index_Drop_Statement FROM [dbo].[vw_Index_MissingIndex] AS mid完整代碼
-- CREATE FUNCTION fn_Index_CreateIndexName CREATE FUNCTION [dbo].[fn_Index_CreateIndexName] (@equality_columns NVARCHAR(4000), _ @Inequality_columns NVARCHAR(4000), @index_handlE INT) RETURNS VARCHAR(128) AS BEGIN DECLAR E @IndexName NVARCHAR(MAX) SET @IndexName = ISNULL(@equali ty_columns,@Inequality_columns) SET @IndexName = LTRIM(REPLACE(@IndexName,"[","_")) SET @IndexName = RTRIM(REPLACE(@IndexName,"]","_")) SET @IndexName = REPLACE(@IndexName,",","") SET @IndexName = REPLACE(@IndexName,"_ _","_") IF LEN(@IndexName) > 120 BEGIN SET @IndexName = SUBSTRING(@IndexName,0,120) END SET @IndexName = @IndexName + CAST(@index_handlE AS NVARCHAR(15)) RETURN @IndexName END GO -- CREATE FUNCTION vw_Index_MissingIndex CREATE VIEW [dbo].[vw_Index_MissingIndex] AS SELECT "[" + d.name + "]" as DBName, [dbo].[fn_Index_CreateIndexName]_ (mid.equality_columns,mid.Inequality_columns,mid.index_handlE) AS ID, REPLACE(mid.equality_columns,","," ASC,") AS equality_columns, REPLACE(mid.Inequality_columns,","," ASC,") AS Inequality_columns, mid.Included_columns, mid.[statement] FROM sys.dm_db_missing_index_details mid INNER JOIN sys.databases d on d.database_id = mid.database_id GO CREATE PROCEDURE [dbo].[usp_Index_MissingIndexCreationStatements] AS DECLARE @IndexCreationPlaceholder_Start AS NVARCHAR(MAX) DECLARE @IndexCreationPlaceholder_End AS NVARCHAR(MAX) -- PREPARE PLACEHOLDER SET @IndexCreationPlaceholder_Start = "IF NOT EXISTS_ (SELECT * FROM {2}.sys.indexes WHERE [name] = ""IX_{0}"" ) BEGIN CREATE NONCLUSTERED INDEX [IX_{0}] ON {1}" SET @IndexCreationPlaceholder_End = " WITH (PAD_INDEX = OFF, _ STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, _ ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] END;" + char(13) + char(10) -- STATEMENT CREATION SELECT DBName, CASE WHEN NOT mid.equality_columns IS NULL AND NOT mid.Inequality_columns IS NULL THEN REPLACE(REPLACE(REPLACE(@IndexCreationPlaceholder_Start,"{0}", _ mid.ID),"{1}",mid.[statement]),"{2}",mid.DBName) + " ( " + COALESCE(mid.equality_columns,"") + " ASC," + COALESCE(mid.Inequality_columns,"") + " ASC )" + COALESCE("INCLUDE ( " + mid.Included_columns + " ) ","") + @IndexCreationPlaceholder_End WHEN mid.equality_columns IS NULL AND NOT mid.Inequality_columns IS NULL THEN REPLACE(REPLACE(REPLACE(@IndexCreationPlaceholder_Start,"{0}", _ mid.ID),"{1}",mid.[statement]),"{2}",mid.DBName) + " ( " + COALESCE(mid.Inequality_columns,"") + " ASC ) " + COALESCE("INCLUDE ( " + mid.Included_columns + " ) ","") + @IndexCreationPlaceholder_End WHEN NOT mid.equality_columns IS NULL AND mid.Inequality_columns IS NULL THEN REPLACE(REPLACE(REPLACE(@IndexCreationPlaceholder_Start,"{0}", _ mid.ID),"{1}",mid.[statement]),"{2}",mid.DBName) + " ( " + COALESCE(mid.equality_columns,"") + " ASC ) " + COALESCE("INCLUDE ( " + mid.Included_columns + " ) ","") + @IndexCreationPlaceholder_End ELSE NULL END AS Index_Creation_Statement, " DROP INDEX [IX_" + mid.ID + "] ON " + mid.[statement] _ + + char(13) + char(10) AS Index_Drop_Statement FROM [dbo].[vw_Index_MissingIndex] AS mid GO
OneAPM 助您輕松鎖定 .NET 應(yīng)用性能瓶頸,通過(guò)強(qiáng)大的 Trace 記錄逐層分析,直至鎖定行級(jí)問(wèn)題代碼。以用戶角度展示系統(tǒng)響應(yīng)速度,以地域和瀏覽器維度統(tǒng)計(jì)用戶使用情況。想閱讀更多技術(shù)文章,請(qǐng)?jiān)L問(wèn) OneAPM 官方博客。
本文轉(zhuǎn)自 OneAPM 官方博客
原文地址:http://www.codeproject.com/Tips/1079651/Automatic-Missing-Non-Clustered-Creation-Statement
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/17518.html
摘要:中面向行和面向列的操作基本是平衡的。用層次化索引,將其表示為更高維度的數(shù)據(jù)。使用浮點(diǎn)值表示浮點(diǎn)和非浮點(diǎn)數(shù)組中的缺失數(shù)據(jù)。索引的的格式化輸出形式選取數(shù)據(jù)子集在內(nèi)層中進(jìn)行選取層次化索引在數(shù)據(jù)重塑和基于分組的操作中很重要。 我們?cè)谏弦黄榻B了 NumPy,本篇介紹 pandas。 pandas入門(mén) Pandas 是基于Numpy構(gòu)建的,讓以NumPy為中心的應(yīng)用變的更加簡(jiǎn)單。 pandas...
摘要:資料分析資料篩選偵測(cè)缺失值補(bǔ)齊缺失值資料轉(zhuǎn)換處理時(shí)間格式數(shù)據(jù)重塑資料學(xué)習(xí)正規(guī)運(yùn)算式處理資料格式,提供高效能,簡(jiǎn)易使用的數(shù)據(jù)格式讓用戶可以快速操作及分析資料。使用平均數(shù),中位數(shù),眾數(shù)等敘述性統(tǒng)計(jì)補(bǔ)齊缺失值。 有90%的有用數(shù)據(jù),都在數(shù)據(jù)庫(kù)中。 數(shù)據(jù) 數(shù)據(jù)類(lèi)型 定性數(shù)據(jù): 敘述特征或種類(lèi),例如:種族,區(qū)域。 定量數(shù)據(jù): 可以被計(jì)數(shù)或測(cè)量,例如:身高,消費(fèi)金額。 定量數(shù)據(jù) 離散數(shù)據(jù)只能...
閱讀 3597·2023-04-26 01:43
閱讀 2984·2021-10-14 09:42
閱讀 5478·2021-09-30 09:59
閱讀 2183·2021-09-04 16:40
閱讀 1220·2019-08-30 15:52
閱讀 838·2019-08-29 17:09
閱讀 2006·2019-08-26 13:37
閱讀 3440·2019-08-26 10:20