Spis treści:

Kategoria:IndeksySQL Server


Pobieranie informacji o rozmiarach indeksów

Po co nam takie informacje?

Skrypty pobierające rozmiary indeksów na danej tabeli nie są stworzone dla zasady. Powstały one w konkretnym celu. Krótki rzut oka na rozmiary indeksów, czyli algorytmicznie rzecz ujmując B-drzew, daje nam ogólny pogląd na zapotrzebowanie pamięciowe SQL Servera (przynajmniej z punktu widzenia indeksów). Nie trzeba chyba wyjaśniać, że mniejsze indeksy są szybsze, a więc lepsze. Mniejszy indeks to mniejsza ilość stron pamięci jakie muszą zostać pobrane/oczytane w celu wykorzystania tego indeksu. Co prawda rozmiar indeksu w porównaniu z rozmiarem samej tabeli nie jest zwykle duży, ale już kilka indeksów na tej samej tabeli złożonych z kilku kolumn mogą spowodować spadki wydajności. W przypadku dużych struktur warto pomyśleć, czy nie da się w odpowiedni sposób zastosować sprytnych indeksów częściowych. Przykładem z życia wziętym jest indeks na hipotetycznej kolumnie daty zwrotu, w której kilkadziesiąt procent wartości jest równa NULL. Stosując indeks częściowy (partial index) można wrzucić do niego tylko te klucze, które mają wartość różną od NULL. Szukając rekordów rozważamy tylko te, które mają tam jakąkolwiek datę, korzystając z tej daty jako filtra. Nie ma potrzeby, aby umieszczać w indeksie NULLe.

Trochę rozwlekły wstęp, bo myślę, że każdy, kto tutaj trafił ma nieco inną potrzebę. Przejdźmy zatem do skryptu.

Pobieranie rozmiaru indeksu w stronach pamięci

SELECT i.name AS [Index name],s.used_page_count [Index size in pages]
FROM sys.dm_db_partition_stats s
JOIN sys.indexes i ON s.[object_id] = i.[object_idAND s.index_id = i.index_id
WHERE s.[object_id] = object_id('dbo.Tabela')
ORDER BY i.name

Wynikiem tego skryptu są pary: nazwa indeksu - rozmiar indeksu. Jednostką rozmiaru są strony pamięci, a całość posortowana jest po nazwie indeksu. Parametrem jest nazwa tabeli, w tym przypadku dbo.Tabela.

Wykorzystanie statystyk indeksu

Druga metoda zwraca wyniki w takiej samej formie, ale korzysta z nieco innej techniki. Tym razem dane pobierane są z funkcji systemowej dm_db_index_physical_stats. Skrypt może wyglądać tak jak poniżej:

SELECT i.name [Index name], SUM(page_count) [Index size in pages]
FROM sys.dm_db_index_physical_stats(
    db_id(), object_id('dbo.Przynaleznosc'), NULLNULL'DETAILED') s
JOIN sys.indexes i
ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
GROUP BY i.name

Metoda ta jest znacznie wolniejsza niż poprzednia, ale daje nam znacznie więcej informacji. Można sprawdzić między innymi to, jaka część danego indeksu znajduje się na konkretnym poziomie drzewa (B-drzewa), w jakim stopniu indeks jest wypełniony, poziom fragmentacji, ilość rekordów i wiele innych. Jeżeli ktoś będzie potrzebował szerszej wiedzy na temat indeksów i ich strukturze w pamięci, najprawdopodobniej tutaj należy skierować swoje poszukiwania.

Kategoria:IndeksySQL Server

, 2013-12-20

Brak komentarzy - bądź pierwszy

Dodaj komentarz
Wyślij
Ostatnie komentarze
Super
Troche zmienilem i smiga'
USE [LiczbyWStringu]
GO

/****** Object: UserDefinedFunction [dbo].[fnGetNumbersDecStringNew] Script Date: 11.11.2022 09:31:13 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


--Moje modyfikacje dla warunku @Licznik
CREATE FUNCTION [dbo].[fnGetNumbersDecStringNew](@str nvarchar(MAX),@Licznik int)
RETURNS @ret TABLE(value decimal(10,2)) AS
BEGIN

--Declare @ret1 TABLE(value nvarchar(255))
Declare @i int
---Declare @str nvarchar(255)
Declare @p nvarchar(255)
Declare @d nvarchar(255)
Declare @LP int
--Declare @Licznik int
--set @licznik =4
set @LP=0

set @p=''
--set @str = 'uaj1s/k60/23.24kl 5MM 34.53C89Lm naj/890.0sie'
set @i = 0
set @d =''

While @i< Len(@str)
Begin
set @i+=1
set @p = SUBSTRING(@str, @i ,1)

If @p>= char(48) and @p < =char(57) or @p= char(46)

Begin
set @d = @d + @p --+','
---char(47) = /
--If SUBSTRING(@k, @i+1,1)<char(48) or SUBSTRING(@k, @i+1,1)>char(57)-- and SUBSTRING(@k, @i+1,1)<char(46)
If SUBSTRING(@str, @i+1,1)<char(46)or SUBSTRING(@str, @i+1,1)=char(47) or SUBSTRING(@str, @i+1,1)>char(57)
or SUBSTRING(@str, @i+1,1)=char(64)

begin
set @lp=@LP+1

If @lp =@licznik
--INSERT INTO @ret VALUES (CAST(@d AS decimal(10,2)))
INSERT INTO @ret VALUES (@d )
---print @d


Begin
set @d=''
end
end
end
end
RETURN
end
--wywolanie jn.
--Select *, (Select* FROM dbo.fnGetNumbersDecStringNew(c4,4))as kl From tblSubstring
--select* FROM dbo.fnGetNumbersDecStringNew('w10w10d20f35',3)
--Select (Select* FROM dbo.fnGetNumbersDecStringNew(c4,1))+(Select* FROM dbo.fnGetNumbersDecStringNew(c4,2))as SumaC1iC2 From tblSubstring where c1=10
GO




Poz JB
Super pomocne Dziękuję Pozdrawiam
Zgadzam się z kolega z 2014-05-26
Świetny artyk€ł !
Ooo chyba użyli varchar-a ;)
Morzna by bylo trohe jasiniej?