Назад | Перейти на главную страницу

Когда индекс не стоит обновлять

есть ли приемлемое соотношение операций чтения и записи, при котором индекс стоит того, или он менее точен, чем это?

Я использую это:

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 операций чтения означают, что мы поддерживаем индекс для нулевой ссылки.
Что я не уверен, так это то, где активность отображается как более сбалансированная - где мне сократить и начать снижать индексы?

Спасибо

Джонатан

Я не думаю, что имеет смысл основывать решение только на количестве операций чтения / записи (если, конечно, вы не читаете == 0, но тогда зачем вам таблица? :-)).

Считают, что:

  • даже если операций чтения мало, они могут занять очень много времени без индекса
  • чтение может быть более критичным по времени, чем запись, поэтому индекс может стоить того, несмотря на снижение производительности записи
  • производительность записи не обязательно должна ухудшаться; Я предполагаю, что большинство современных СУБД могут отложить обновление индекса до тех пор, пока оно не понадобится, например, несколько последовательностей INSERT должны вызывать только одно обновление индекса

Короче, как всегда, единственный совет: профилируйте перед оптимизацией. Нет простого ярлыка: - /.

Чего вы пытаетесь достичь? вы пытаетесь улучшить производительность ввода-вывода? у вас мало места на диске? Преждевременная оптимизация - это корень всех зол!

Придерживайтесь быстрых результатов, таких как 0 чтений и 100000000 записей. Все остальное - компромисс. Если на вашем сервере есть запас, но нет места на диске, начните работать в обратном направлении с самого низкого отношения чтения к записи и следите за производительностью.

Возможно, будет разумнее изучить другие альтернативы, такие как оптимизация процедур / запросов, добавление сжатия страниц, добавление дискового пространства / ОЗУ и т. Д.