Когда индекс не стоит обновлять
Существует ли приемлемое соотношение операций чтения и записи, которое делает индекс полезным, или оно меньше, чем это?
Я использую это:
WITH UnusedIndexQuery ( Object_ID, ObjectName, IndexName, Index_ID, Reads, Writes, Rows )
AS ( SELECT
s.object_id ,
objectname = OBJECT_NAME(s.OBJECT_ID) ,
indexname = i.name ,
i.index_id ,
reads = user_seeks + user_scans + user_lookups ,
writes = user_updates ,
p.rows
FROM
sys.dm_db_index_usage_stats s
JOIN
sys.indexes i
ON
i.index_id = s.index_id
AND s.OBJECT_ID = i.OBJECT_ID
JOIN
sys.partitions p
ON
p.index_id = s.index_id
AND s.OBJECT_ID = p.OBJECT_ID
WHERE
OBJECTPROPERTY(s.OBJECT_ID, 'IsUserTable') = 1
AND s.database_id = DB_ID()
AND i.type_desc = 'nonclustered'
AND i.is_primary_key = 0
AND i.is_unique_constraint = 0
AND p.rows > 10000
),
IndexSizes ( schemaname, tablename, object_id, indexname, index_id, indextype, indexsizekb, indexsizemb, indexsizegb )
AS ( SELECT
sys_schemas.name AS SchemaName ,
sys_objects.name AS TableName ,
sys_objects.[object_id] AS object_id ,
sys_indexes.name AS IndexName ,
sys_indexes.index_id AS index_id ,
sys_indexes.type_desc AS IndexType ,
partition_stats.used_page_count * 8 AS IndexSizeKB ,
CAST(partition_stats.used_page_count * 8 / 1024.00 AS DECIMAL(10,
3)) AS IndexSizeMB ,
CAST(partition_stats.used_page_count * 8 / 1048576.00 AS DECIMAL(10,
3)) AS IndexSizeGB
FROM
sys.dm_db_partition_stats partition_stats
INNER JOIN sys.indexes sys_indexes
ON
partition_stats.[object_id] = sys_indexes.[object_id]
AND partition_stats.index_id = sys_indexes.index_id
AND sys_indexes.type_desc <> 'HEAP'
INNER JOIN sys.objects sys_objects
ON
sys_objects.[object_id] = partition_stats.[object_id]
INNER JOIN sys.schemas sys_schemas
ON
sys_objects.[schema_id] = sys_schemas.[schema_id]
AND sys_schemas.name <> 'SYS'
)
SELECT
[IndexSizes].[tablename] ,
[IndexSizes].[indexname] ,
[IndexSizes].[indextype] ,
[IndexSizes].[indexsizekb] ,
[IndexSizes].[indexsizemb] ,
[IndexSizes].[indexsizegb] ,
UnusedIndexQuery.Reads ,
UnusedIndexQuery.Writes ,
CAST(CASE WHEN [Reads] = 0 THEN 1
ELSE [Reads]
END / CASE WHEN [Writes] = 0 THEN 1
ELSE writes
END AS NVARCHAR(8)) + ':1' AS [Benefit Ratio (Read:Write)] ,
UnusedIndexQuery.[Rows]
FROM
UnusedIndexQuery
INNER JOIN IndexSizes
ON UnusedIndexQuery.object_id = IndexSizes.object_id
AND UnusedIndexQuery.index_id = IndexSizes.index_id
ORDER BY
CASE WHEN [Reads] = 0 THEN 1
ELSE [Reads]
END / CASE WHEN [Writes] = 0 THEN 1
ELSE writes
END ,
reads ,
[Writes] DESC ,
[indexsizemb] DESC
чтобы получить представление о состоянии преимуществ моих индексов.
С двух сторон результатов я ясен - 1 000 000 операций чтения и 0 операций записи = хороший индекс для ускорения поиска данных, 1 000 000 операций записи и 0 операций чтения означает, что мы поддерживаем индекс для нулевой ссылки.
В чем я не уверен, так это где активность показана как более сбалансированная - где я могу сделать индексы сокращения и начала отбрасывания?
Спасибо
Джонатан
2 ответа
Я не думаю, что имеет смысл основывать решение только на количестве операций чтения / записи (если, конечно, вы не читаете ==0, но тогда почему у вас есть таблица?:-)).
Считают, что:
- даже если чтения мало, они могут быть очень трудоемкими без индекса
- чтения могут быть более критичными по времени, чем записи, поэтому индекс может стоить того, несмотря на снижение производительности записи
- производительность записи не обязательно страдает; Я бы предположил, что большинство современных СУБД могут задерживать обновление индекса до тех пор, пока оно не потребуется, поэтому, например, много последовательных вставок должны вызывать только одно обновление индекса
Короче говоря, как всегда, единственный совет: профиль перед оптимизацией. Там нет простого ярлыка:-/.
Чего ты пытаешься достичь? Вы пытаетесь улучшить производительность ввода-вывода? у вас мало места на диске? Преждевременная оптимизация - корень всего зла!
Придерживайтесь быстрых побед, таких как 0 читает и 100 000 000 записей. Все остальное - компромисс. Если на вашем сервере есть запас, но нет места на диске, то начните работать в обратном направлении с самого низкого отношения чтения к записи и следите за производительностью.
Может быть разумнее изучить другие альтернативы, такие как оптимизация процедур / запросов, добавление сжатия страниц, добавление дискового пространства /RAM и т. Д.