坏索引的定义是什么?我们如何决定?我们应该有什么逻辑?

Mon*_*RPG 2 performance sql-server optimization index-tuning sql-server-2014 performance-tuning

互联网上有查询发现坏索引

虽然他们的逻辑很简单

如果写入计数 > 读取计数 = 坏索引

这是一个示例查询

    SELECT  OBJECT_NAME(s.object_id) AS 'Table Name',
        i.name AS 'Index Name',
        i.index_id,
        user_updates AS 'Total Writes',
        user_seeks + user_scans + user_lookups AS 'Total Reads',
        user_updates - ( user_seeks + user_scans + user_lookups ) AS 'Difference'
FROM    sys.dm_db_index_usage_stats AS s WITH ( NOLOCK )
        INNER JOIN sys.indexes AS i WITH ( NOLOCK ) ON s.object_id = i.object_id
                                                       AND i.index_id = s.index_id
WHERE   OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1
        AND s.database_id = DB_ID()
        AND user_updates > ( user_seeks + user_scans + user_lookups )
        AND i.index_id > 1
ORDER BY 'Difference' DESC,
        'Total Writes' DESC,
        'Total Reads' ASC ;
-- Index Read/Write stats for a single table
SELECT  OBJECT_NAME(s.object_id) AS 'TableName',
        i.name AS 'IndexName',
        i.index_id,
        SUM(user_seeks) AS 'User Seeks',
        SUM(user_scans) AS 'User Scans',
        SUM(user_lookups) AS 'User Lookups',
        SUM(user_seeks + user_scans + user_lookups) AS 'Total Reads',
        SUM(user_updates) AS 'Total Writes'
FROM    sys.dm_db_index_usage_stats AS s
        INNER JOIN sys.indexes AS i ON s.object_id = i.object_id
                                       AND i.index_id = s.index_id
WHERE   OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1
        AND s.database_id = DB_ID()
        AND OBJECT_NAME(s.object_id) = 'AccountTransaction'
GROUP BY OBJECT_NAME(s.object_id),
        i.name,
        i.index_id
ORDER BY 'Total Writes' DESC,
        'Total Reads' DESC ;,
Run Code Online (Sandbox Code Playgroud)

然而问题就这么简单吗?我们可以称所有写>读=坏索引吗?

是否有更好的 SQL 查询逻辑可以定义坏索引?

让我们忽略确保数据完整性的索引,例如唯一约束

让我们假设索引每分钟更新和使用一次

我正在使用 SQL Server 2014,这里查询生成的结果

在此处输入图片说明

Dav*_*ett 5

然而问题就这么简单吗?

绝对不。不幸的是,它在应用程序之间可能会有很大差异,因此虽然有许多“经验法则”,就像您所说的那样,除了“从未使用过的索引是一种浪费”之外,没有一个是普遍适用的。

我们可以称所有写>读=坏索引吗?

如果该索引用于强制执行完整性(即它是唯一索引或支持外键),那么该事实通常胜过性能要求。此外,写入可能主要发生在无关紧要的时间(可能在半夜进行批量更新),或者这些读取尽可能快可能非常重要,因此缓慢的写入是值得付出的代价。

在考虑这些问题时,请始终考虑您正在查看的任何数字所涵盖的时间段。可能是本周某个指数看起来未充分利用,但下周是新报告期的开始,因此用户正在执行一组不同的操作,而该指数突然看起来更有用了。

永远不要使用经验法则作为生活的硬性规定。将它们用作建议,并根据您对特定应用程序需求的了解仔细考虑结果。

你能扩大你的答案并添加更多细节吗?

除非你有更具体的问题,否则不能不写一整本书,这是一个非常广泛的领域。事实上,关于这个主题已经写了很多整本书...... http://use-the-index-luke.com/是一个很好的起点。