JOIN、GROUP BY、WHERE 或 ORDER BY 的操作)尤其有效。
索引通过以不同的顺序存储部分数据的副本,从而实现更快速的访问,就像为一本书添加目录一样。
如果您想深入了解索引如何工作以及如何使用它们,可以查看我们关于索引的详细说明文章或视频课程。这些资源涵盖从索引和 B+树的工作原理到索引的添加时机全方面内容。
尽管索引带来的性能提升令人印象深刻,但为数据库中的每个表的每一列都添加索引并不是一个好主意,因为过多的二级索引可能会带来一些问题。
以下是使用过多二级索引可能导致的一些弊端:
添加索引的首要问题是它需要占用额外的存储空间。具体占用量取决于表的大小和索引的列数,通常为表总大小的一小部分。基本索引仅需存储索引列的值以及指向表中行的指针:
当数据集较大时,为表添加多个索引可能会快速增加额外存储使用量。
添加索引后,表中插入、更新或删除行时索引需同步更新,这会导致写操作变慢。在添加索引之前,需仔细评估表的写操作频率,以及能否接受写入性能的下降。
例如,一个应用程序进行一次含百万条记录的批量插入:
如果插入操作由用户触发并需要等待,则需要重新评估写操作的影响。
保持数据库高效的关键是识别并移除未使用的索引。以下 SQL 查询可帮助发现未使用的索引(将 your_database_name 替换为您的数据库名称):
SQLSELECT table_name, index_name, non_unique, seq_in_index, column_name, collation, cardinality, sub_part, packed, index_type, comment, index_comment
FROM information_schema.STATISTICS
WHERE table_schema = 'your_database_name'
AND index_name != 'PRIMARY'
AND (cardinality IS NULL OR cardinality = 0)
ORDER BY table_name, index_name, seq_in_index;
该查询检查每个索引的唯一值数量(cardinality)。值为 0 表示索引未使用。
移除未使用索引时,用以下 SQL:
SQLALTER TABLE your_table_name DROP INDEX your_index_name;
如果发现某些索引实际在使用,但经过思考后觉得相关权衡不值得,可以逐个审查这些索引以决定是否保留或移除。
获取当前数据库所有表的索引列表:
SQLSELECT * FROM information_schema.statistics;
在实际移除索引之前,可以利用 MySQL 不可见索引(Invisible Indexes) 测试删除索引的效果。使用不可见索引时,索引保持原样,但对查询不可见。
设置不可见索引:
SQLALTER TABLE your_table_name ALTER INDEX your_index_name INVISIBLE;
测试完影响后,如果索引仍然需要,可以再次设为可见:
SQLALTER TABLE your_table_name ALTER INDEX your_index_name VISIBLE;
注意:
尽管索引可以显著提高查询性能,但其添加需考虑权衡:
索引是否值得添加,取决于应用程序的具体需求以及能接受的代价。当添加或移除索引时,始终应测试受影响的查询性能,以确保操作符合预期并不会造成性能下降。如果未看到显著的性能改善,放弃添加索引可能是更好的选择。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>接收一个项目,其中一个字段的关键字为index,执行查询方法时出现如下异常信息:
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'index,value,status,create_time,update_time FROM config WHERE grou' at line 1
起初看这个异常有些摸不着头脑,将SQL复制到客户端程序中,执行依旧出现问题:
SELECT id,group_id,index,value,status,create_time,update_time FROM config WHERE group_id = 1 AND status = '1' ORDER BY id DESC
于是就开始删减字段进行验证排查,发现是index与关键字冲突导致的。
针对这种情况,如果可以进来将表结构的字段进行修改,修改为非mysql的关键字。如果项目不允许修改,则可以用如下格式来表示字段:
'key' 或 'index'
针对上面的语句修改一下就是:
SELECT id,group_id,'index',value,status,create_time,update_time FROM config WHERE group_id = 1 AND status = '1' ORDER BY id DESC
而且凡是使用到该字段的地方都需要使用单引号,否则就会出现上面所展示的异常信息。
index是数据库的物理结构,它只是辅助查询的,它创建时会在另外的表空间(mysql中的innodb表空间)以一个类似目录的结构存储。索引要分类的话,分为前缀索引、全文本索引等;
因此,索引只是索引,它不会去约束索引的字段的行为(那是key要做的事情)。如,create table t(id int,index inx_tx_id (id));
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>