索引是你的数据库模式的一个关键部分。它们通过帮助数据库定位数据来提高工作负载的性能,而不需要扫描表中的每一行。尽管为你的工作负载用来过滤数据的每一列创建一个索引可能是很诱人的,但考虑索引的性能权衡是很重要的。虽然索引极大地提高了使用过滤器的读取查询的性能,但是它们确实是以写入性能为代价的:数据必须被写入表中的所有索引。
CockroachDB有一组功能可以帮助你分析索引的使用情况,并为你是否应该创建新的索引,或者放弃或更新现有的索引提供建议。在这篇博文中,我们将告诉你如何使用这些功能。
使用语句页来避免全扫描
当数据库没有办法避免读取一个表的所有数据以满足查询时,查询就会引起全表扫描。全表扫描会导致数据库读取磁盘上一个表的每一个字节,这对大表来说是非常昂贵的。例如,像SELECT * FROM t WHERE id = 10 这样的查询,如果表的 "id "列上没有索引,就会引起全表扫描。
全扫描往往是优化的机会,是更好的索引策略的信号。 那些过滤子集行但被迫扫描全表的查询将受益于二级索引,以允许更好地修剪扫描的行,减少IO,并提高整体性能。识别哪些语句是通过全表扫描执行的,一个简单的方法是点击SQL活动页面下的语句标签,选择过滤器 "只显示全表扫描的语句"。
由于CockroachDB将语句概览页面上的值聚集在选定的时期,你可能会看到表上的语句指纹(这是通过用下划线替换数字和字符串等字面值来表示的SQL语句),其最近的执行可能没有使用全扫描,所以下一步是通过点击相关的语句,进入其细节页面。
从那里选择 "解释计划 "选项卡。在那里,你将能够看到该报表指纹ID在选定期间使用的所有计划。计划表的其中一列是最后执行时间,另一列是全面扫描,这将使你能够确定最近的计划执行是否是全面扫描。
你也可以点击每个计划,查看其完整的查询计划。
除了具有完全扫描的语句,你还可以查看具有较高执行时间的语句。
现在你已经有了一些你可能想要创建或改进现有索引的语句,让我们来为它们寻找建议。
为了找到索引建议,你可以使用强大的EXPLAIN 命令,它可以返回优化器为一个查询选择的语句计划的信息。你也可以使用EXPLAIN ANALYZE ,它将实际执行SQL查询,并生成一个带有执行统计数据注释的语句计划。
注意EXPLAIN输出的底部的信息:关于创建和替换索引的建议。这些建议是数据库对你如何用不同的索引来改进单个语句的最佳猜测。
一个常见的错误是在没有STORING子句的情况下创建一个二级索引,这可能会导致索引连接。索引连接可能很慢,因为它们需要为二级索引中扫描的每一条记录在主索引中进行查找。在这种情况下,你可能会得到建议,用一个包含STORING子句的索引来替换这个索引。
在你创建或修改索引之后,你可以回到所选语句的同一个细节页面,再次检查统计数据,你将能够观察到更新的性能信息,现在新的索引已经到位。
如果一个表中的数据量发生了重大变化,表中引入了新的列,或者增加了新的访问模式,那么用上面提到的功能来监控工作负载的性能是很好的做法,这样你就可以确保工作负载一直处于最佳状态。
使用索引统计来寻找使用率低或没有使用率的索引
在 "数据库 "页面上,点击任何一个数据库以查看它所包含的表的列表。该视图还将显示每个特定表的索引数量。点击表的名称将把你带到表的详细信息页面,在那里你可以看到所有索引的列表和每个索引的统计信息,包括名称、总读数和最后使用时间。
在索引统计表上,你可以看到是否有索引的总读数很低,从未使用过或只是在很久以前使用过。这些索引可能会降低你的写性能,而对读性能没有明显的积极影响,所以它们是可以考虑放弃的好人选。
如果你最近对索引做了改变,你可以点击Reset all index stats ,这将清除集群中的所有数据,让你只关注最新的指标进行分析。
你也可以用CLI重设索引统计,SELECT crdb_internal.reset_index_usage_stats() 。
敬请关注今年秋天在v22.2中的一些更新,这将使你更容易看到索引的推荐!