我意识到,当为“ORDER BY”使用的列创建索引时,对MySQL查询的响应变得更快,例如
SELECT username FROM table ORDER BY registration_date DESC
现在我想知道我应该创建哪些索引来优化请求时间。 例如,我经常使用以下查询:
SELECT username FROM table WHERE
registration_date > ".(time() - 10000)."
SELECT username FROM table WHERE
registration_date > ".(time() - 10000)."
&& status='active'
SELECT username FROM table WHERE
status='active'
SELECT username FROM table ORDER BY registration_date DESC
SELECT username FROM table WHERE
registration_date > ".(time() - 10000)."
&& status='active'
ORDER BY birth_date DESC
问题1: 我应该为前三种请求类型设置单独的索引吗? (即列“registration_date”的一个索引,“status”列的一个索引,以及两者组合的另一个列?)
问题2: 不同的指数是否独立用于“WHERE”和“ORDER BY”?比如说,我有一个列为“status”和“registration_date”的组合索引,另一个索引仅用于“birth_date”列。我应该为三列设置另一个组合索引(“status”,“registration_date”和“birth_date”)吗?
答案 0 :(得分:3)
索引或查询优化没有严格的规则。每个案例都需要考虑和审查。
但是,一般来说,您可以而且应该将索引添加到经常排序或在WHERE语句中使用的列。 (对问题2的回答 - 不,相同的索引可能用于ORDER BY
和WHERE
)是否执行多列索引或单列索引取决于查询的频率。此外,您应该注意,使用索引合并优化,mySQL可以将单列索引组合:
索引合并方法用于检索具有多个范围的行 扫描并将其结果合并为一个。合并可以产生 工会,交叉点或其基础的交叉点 扫描。此访问方法合并来自单个表的索引扫描;它 不会跨多个表合并扫描。
(更多阅读:http://dev.mysql.com/doc/refman/5.0/en/index-merge-optimization.html)
多列索引还要求您注意构造查询,使得索引列的使用与索引中的列顺序匹配:
如果列不形成最左边的列,则MySQL无法使用索引 索引的前缀。假设您显示了SELECT语句 这里:
SELECT * FROM tbl_name WHERE col1 = val1; SELECT * FROM tbl_name WHERE col1 = val1 AND col2 = val2;
SELECT * FROM tbl_name WHERE col2 = val2; SELECT * FROM tbl_name WHERE col2 = val2 AND col3 = val3;
如果(col1,col2,col3)上存在索引,则只有前两个查询 使用索引。第三和第四个查询确实涉及索引 列,但是(col2)和(col2,col3)不是最左边的前缀 (col1,col2,col3)。
请记住,索引DO具有自己的性能考虑因素 - 可以对表进行“过度索引”。每次插入记录或修改索引列时,都必须重建索引/索引。这确实需要资源,并且根据表的大小和结构,它可能会导致索引构建操作处于活动状态时响应速度降低。
使用EXPLAIN
确切了解您的查询中发生了什么。分析,实验,不要过度。霰弹枪方法不适合数据库优化。
<强>文档强>
答案 1 :(得分:1)
引用this page:
[指数]会降低您的更新和插入速度。
这是你必须计算的权衡。要优化表格,您应该将索引仅放在最有可能应用条件的列中 - 您拥有的索引越多,数据更改操作就越慢。从这个意义上说,我个人认为创建组合索引并没有太大的优点 - 如果你为3列创建索引的所有7种可能的排列,你肯定会对你的更新和插入产生更多的拖累,而不仅仅是使用3列的3个索引(甚至可以说是有争议的)。另一方面,如果数据被编辑得太多,很多比SELECT
更少,那么索引可以真正帮助你加快速度。
需要考虑的其他事项(再次引用上面的内容):
如果你的桌子非常小,那么使用索引要比把它留下来更糟糕,让它进行表扫描。索引实际上只对具有大量行的表格派上用场。
答案 2 :(得分:1)
是的,最好在您经常使用的列上添加索引,包括order by和where子句中的索引。
但要注意:如果你有索引,UPDATES,INSERTS和DELETE会减慢。
这是因为在这样的操作之后,索引也必须更新。
因此,根据经验法则:如果您的应用程序是读取密集型的,请使用您认为有帮助的索引。
如果您的应用程序经常更新数据,请注意,因为索引可能会变慢。
如果有疑问,你必须简单地弄脏手,并研究EXPLAIN的结果。
答案 3 :(得分:1)
对于前两个示例,您可以使用一个索引来满足它们:{registration_date,status}。这样的索引可以支持第一项(registration_date)或两者上的过滤器。
但是,它不仅适用于状态。关于地位的问题是地位的选择性。也就是说,有多少记录具有status =“active”。如果这个比例很高(因此,平均而言,每个数据库页面都会有一个活动记录),那么索引可能无济于事。按顺序排序比较棘手。我不知道mysql是否为此目的使用索引。通常,使用索引对整个记录进行排序比仅仅对记录进行排序更少更有效。使用索引会导致页面中记录的随机访问模式,这可能会导致大于页面缓存的表出现严重的性能问题。
答案 4 :(得分:0)
在select语句中使用explain函数来确定连接速度减慢的位置(引用的行越多,它就越慢)。然后将索引应用于这些列。
EXPLAIN SELECT * FROM table JOIN table 2 ON a = b WHERE conditions;