32
Table Indexing for the .NET Developer Denny Cherry [email protected] twitter.com/mrdenny

Table Indexing for the .NET Developer

  • Upload
    etan

  • View
    21

  • Download
    0

Embed Size (px)

DESCRIPTION

Table Indexing for the .NET Developer. Denny Cherry [email protected] twitter.com/ mrdenny. About Me. Independent Consultant Founder of SQL Excursions Author or Coauthor of 5 books 8 + SQL Mag articles Dozens of other articles Microsoft MVP Microsoft Certified Master VMware vExpert. - PowerPoint PPT Presentation

Citation preview

SQL Server Indexing for the Client Developer

Table Indexing for the .NET DeveloperDenny [email protected]/mrdenny

About MeIndependent ConsultantFounder of SQL ExcursionsAuthor or Coauthor of 5 books8+ SQL Mag articlesDozens of other articlesMicrosoft MVPMicrosoft Certified MasterVMware vExpert2

Todays GoalsIntroduce the different kinds of indexesCommon Misconceptions about indexesDownsides to indexesIntroduce advanced index tuning techniquesQ & ATodays GoalsIntroduce the different kinds of indexesCommon Misconceptions about indexesDownsides to indexesIntroduce advanced index tuning techniquesQ & ADifferent Kinds of IndexesFive Kinds of IndexesClusteredNon-clusteredFull TextXMLColumnStore IndexesTheres new stuff coming in SQL Server 2012Semantic SearchClustered Indexes1 Clustered Index per tableContain Full Copy of row data within in the indexUp to 16 indexed columns can be part of the index(15 if the table contains any XML indexes)Primary Key will by default be the Clustered IndexMust be created on the same filegroup as the tableClustered Indexes should be as narrow as possibleWhile not required, they are highly recommendedNon-clustered IndexUp to 999 per table Starting with SQL Server 2008255 in SQL Server 2005 and belowUp to 16 indexed columns in the indexNon-indexed columns can be included via INCLUDE statementNon-Clustered indexes always contain the clustered index columns (when table has a clustered index)When table is a heap, the Row ID is stored in every non-clustered index.Can be created on any filegroup within the databaseCan be filtered indexes to include fewer rows in the index.

The number of indexes has not been changed as of SQL Server 2012 CTP37Differences between unique and non-unique clustered indexesNon-Unique clustered indexes have an extra column called the uniqueifier which ensures that values within the index are unique. Uniqueifier is only used for rows which are not unique.EmpIdUniqufier12340415670718Full Text IndexesNot accessed via normal SELECT statementsRequire use of a predicate:CONTAINSCONTAINSTABLEFREETEXTFREETEXTTABLECan be used to search binary values (doc, docx, xls, pdf) stored within the database.Natural Language SearchCan index XML documents, but only indexes the values, not the tags.Full Text Indexes (SQL 2005 and below)Created and managed outside of the database via Microsoft Search ServiceBacked up with the database (starting in SQL 2005)Searches entire index and returns all matches, which you then filter against your normal table to return correct set of rows.

Full Text Indexes (SQL 2008 and up)Now stored within the databaseCommand is still parsed via MS Search service, but looking is done nativelyFull text search now only searches the required subset of rowsWhen creating your indexes use an identity field as the key to improve query performance.XML IndexesAllows you to index specific nodes of the XML document249 XML Indexes pre tableRequires a Clustered Index on the tableEach xml column can have a single primary XML index and multiple secondary XML indexesXML Indexes can only be created on a single XML ColumnNo online rebuildsNot available for XML variables. Only used on tables.Primary XML IndexWhen created creates a hidden node tableContains base table primary key and 12 columns of info about every node within the XML valueEffectively the clustered index on the node tableBase Table Clustered Index ValueNode id from the node tableIncreases storage 200-500%Secondary XML IndexesNon-Clustered Indexes on the hidden node tableThree kinds of secondary indexesPATH index on the node id (path) and the valueVALUE index is on the value and the node id (path)PROPERTY index is on the base tables clustered index, node id (path) and the valueTodays GoalsIntroduce the different kinds of indexesCommon Misconceptions about indexesDownsides to indexesIntroduce advanced index tuning techniquesQ & ACommon Misconceptions about indexesIndexes dont require maintenanceIf I create one index for each column in my where clause Ill be fineThe table is sorted based on the order of the Clustered IndexClustered Indexes are required

Todays GoalsIntroduce the different kinds of indexesCommon Misconceptions about indexesDownsides to indexesIntroduce advanced index tuning techniquesQ & ADownsides to indexesIndexes take up spaceOn large complex databases the indexes can take up more space than the tableData is duplicated in each index which contains the columnIndexes slow down insert, update, delete (especially full text indexes) statementsUsing the wrong index can be slower than using no indexEncrypted data cant be effectively indexedTodays GoalsIntroduce the different kinds of indexesCommon Misconceptions about indexesDownsides to indexesIntroduce advanced index tuning techniquesQ & AAdvanced Index Tuning TechniquesFillfactorTells the SQL Server how much free space to leave in the leaf level pages.PaddingTells the SQL Server to use the Fillfactor setting to leave free space in the intermediate-level pages.Online RebuildsData CompressionWhat is a ColumnStore Index?Totally new and different approach to indexingData is stored via columns not rowsEach column is stored separately, then compressed using VertiPak compression engineSQL Servers first B-Tree less indexHow does ColumnStore do that?C1C2C3C5C6C4

Existing PagesNeeded ColumnsAs the column store index is scanned looking for matching values the min and max values are looked at to see if that row group needs to be scanned at all based on the WHERE clause of the query.Data is not sortedThere is no such thing as a key in a column store index

22ColumnStore: Use CaseData continues to grow, but performance requirements stay the sameMany data warehouses approach PB rangesData needs to be filtered, aggregated, and grouped despite the size of the dataset23LimitationsUnsupported Data Types includeUniqueidentifierBlobNumeric (19,2) or higherRead OnlyOUTER JOINs using ColumnStore dont perform wellColumn StoreDemo!Using the Advanced Index Tuning TechniquesCREATE INDEX MyIndex ON dbo.MyTableON (Col1, Col5, Col3)INCLUDE (Col4, Col2)WHERE Col6 = Value3WITH (FILLFACTOR=70, PAD_INDEX=ON, ONLINE=ON, DATA_COMPRESSION = ROW | PAGE);Physical Index B-Tree LayoutClustered (BOL 2005 / 2008)Non-Clustered (BOL 2005 / 2008)

How large are my indexes?SELECT *FROM sys.dm_db_index_physical_stats (db_id(), object_id(table_name), null, null, detailed)Database IdObject IdIndex IdPartition NumberMode (NULL | Limited, Sampled, Detailed)

What Indexes are being used?DECLARE @dbid INT , @dbName VARCHAR(100); SELECT @dbid = DB_ID() , @dbName = DB_NAME(); WITH partitionCTE (OBJECT_ID, index_id, row_count, partition_count)AS( SELECT [OBJECT_ID] , index_id , SUM([ROWS]) AS 'row_count' , COUNT(partition_id) AS 'partition_count' FROM sys.partitions GROUP BY [OBJECT_ID] , index_id) SELECT OBJECT_NAME(i.[OBJECT_ID]) AS objectName , i.name , CASE WHEN i.is_unique = 1 THEN 'UNIQUE ' ELSE '' END + i.type_desc AS 'indexType' , ddius.user_seeks , ddius.user_scans , ddius.user_lookups , ddius.user_updates , cte.row_count , CASE WHEN partition_count > 1 THEN 'yes' ELSE 'no' END AS 'partitioned?' , CASE WHEN i.type = 2 And i.is_unique = 0 THEN 'Drop Index ' + i.name + ' On ' + @dbName + '.dbo.' + OBJECT_NAME(ddius.[OBJECT_ID]) + ';' WHEN i.type = 2 And i.is_unique = 1 THEN 'Alter Table ' + @dbName + '.dbo.' + OBJECT_NAME(ddius.[OBJECT_ID]) + ' Drop Constraint ' + i.name + ';' ELSE '' END AS 'SQL_DropStatement'FROM sys.indexes AS iINNER Join sys.dm_db_index_usage_stats ddius ON i.OBJECT_ID = ddius.OBJECT_ID And i.index_id = ddius.index_idINNER Join partitionCTE AS cte ON i.OBJECT_ID = cte.OBJECT_ID And i.index_id = cte.index_idWHERE ddius.database_id = @dbidORDER BY 1, (ddius.user_seeks + ddius.user_scans + ddius.user_lookups) ASC , user_updates DESC;

Dont worry, you can download this from my blog, or from sqlfool.com (where I stole it from).More Readinghttp://mrdenny.com/res/table-indexing-netQ & ADenny [email protected]://itke.techtarget.com/sql-server/http://www.twitter.com/mrdennyPlease rate my presentation at http://speakerrate.com/mrdenny32