Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL索引-有多少足够?_Mysql_Indexing_Performance_Logging - Fatal编程技术网

MySQL索引-有多少足够?

MySQL索引-有多少足够?,mysql,indexing,performance,logging,Mysql,Indexing,Performance,Logging,我正试图微调我的MySQL服务器,以便检查我的设置,分析慢速查询日志,并尽可能简化查询 如果索引正确,有时就足够了,有时不行。我在某个地方读到过(如果这是愚蠢的,请纠正我),超过我需要的索引会产生相同的效果,比如如果我没有任何索引 有多少索引就足够了?你可以说这取决于数百个因素,但我很好奇如何清理我的mysql slow.log以减少服务器负载 此外,我还看到一些“有趣”的日志条目,如下所示: # Query_time: 0 Lock_time: 0 Rows_sent: 22 Rows_

我正试图微调我的MySQL服务器,以便检查我的设置,分析慢速查询日志,并尽可能简化查询

如果索引正确,有时就足够了,有时不行。我在某个地方读到过(如果这是愚蠢的,请纠正我),超过我需要的索引会产生相同的效果,比如如果我没有任何索引

有多少索引就足够了?你可以说这取决于数百个因素,但我很好奇如何清理我的
mysql slow.log
以减少服务器负载

此外,我还看到一些“有趣”的日志条目,如下所示:

# Query_time: 0  Lock_time: 0  Rows_sent: 22  Rows_examined: 44
SELECT * FROM `categories` ORDER BY `orderid` ASC;

该表正好包含22行,索引设置在
orderid
中。为什么这个查询最终会出现在日志中?如果44行只包含22行,为什么还要检查它呢?

没有“最佳”索引数的幻数。基本规则是:为经常使用和/或需要快速运行的查询添加索引


拥有“太多”索引不应该会减慢查询速度,但如果每个添加的索引都添加了一小段时间来添加/更新数据库中的项(因为它也会修改索引),并且会增加一小段空间。但是,如果您只是根据需要添加索引,这可能不是什么大问题。

一般来说,您应该在所有主键(您没有选择)、所有外键以及通常用于获取行的任何其他字段上都有索引


例如,如果我通常按用户名查找用户,即使用户ID是主键,我也会对其进行索引。

有多少索引完全取决于您运行的查询、正在执行的连接类型(如果有)、表中存储的数据类型以及表的大小(以及许多其他因素)。这真的没有确切的科学依据。在你的武器库中,找出如何优化查询的最好工具是。使用explain,您可以了解正在关闭的联接类型、可能使用的键以及使用的键(如果有)以及联接中每个表检查了多少行

使用此信息,您可以决定如何为表设置键和/或修改查询以提高效率。explain的语法非常简单

EXPLAIN SELECT * FROM `categories` ORDER BY `orderid` ASC;
注意,explain不会实际运行查询。因此,如果您使用它来调试一个运行需要5分钟的查询,explain仍然会非常快


添加索引时确实需要小心,因为它们确实会导致插入和更新速度变慢,而且在非常大的表上,这种性能影响可能会变得明显。尤其是当同一个表用于大量读取时。虽然添加大量索引通常不会降低查询的性能,但您仍然应该只添加它们,因为索引可以加速SELECT查询,但它会减慢INSERT/UPDATE/DELETE查询的速度,因为它们还需要更新索引,而不仅仅是行


这只是个人观点(我没有事实支持),但我认为如果有一个查询需要很长时间,并且索引会加快它的速度,那就去做吧!如果您添加的索引没有任何好处(例如,没有查询会加快速度),则会出现“太多”索引。例如,一个愚蠢的做法是在每一列上放置一个索引“仅仅因为”

索引的数量和做得太多的行将取决于很多因素。在像“categories”表这样的小表上,您通常不想要或不需要索引,这实际上会影响性能。原因是读取索引需要I/O(即时间),然后检索与匹配行关联的记录需要更多的I/O和时间。如果只查询索引中包含的列,则会出现异常

在您的示例中,您正在检索所有的列,并且只有22行,因此只进行表扫描并对这些列进行排序而不使用索引可能会更快。优化器可能/应该这样做并忽略索引。如果是这样的话,那么索引只会占用空间,没有任何好处。如果您的“类别”表经常被访问,您可能需要考虑将其绑定到内存中,这样DB服务器就可以访问它,而不必一直到磁盘。 添加索引时,需要平衡磁盘空间、查询性能以及更新和插入表的性能。与每天有数百万次更新的表相比,您可以在静态且变化不大的表上创建更多索引。此时,您将开始感受到索引维护的影响。但是,在您的环境中什么是可以接受的,并且只能由您和您的组织来决定


进行分析时,请确保生成/更新表和索引统计信息,以便确保计算准确

还要记住,MySQL对每个select
语句最多使用一个索引(尽管如果使用连接,它也可以对每个连接使用一个索引)。因此,仅仅因为索引是对磁盘空间的浪费,而且会降低数据库的写入速度。如果您通常在两列上使用where语句,则对包含这两列的列执行一个索引,这将比仅对其中一列进行索引快得多。

我猜它执行排序,因此它会以某种方式多次检查同一行:xexplain SELECT*FROM
categories
orderby
orderid
ASC返回的内容@R.Bemrose:如果我更正了,它将返回一个额外的:usingfilesort。也许这就是问题所在?“一个愚蠢的做法是在每一列上都放置一个索引”,仅仅因为“”-这完全可以,但我希望尽可能地消除缓慢的日志条目。否则,感谢您对插入/更新/删除的想法!非常感谢。这对我来说是最清楚、最有帮助的答案!如何将表“固定”到内存中?如何告诉MySQL将表固定到内存中?一种方法是