ORDER BY A*B 的 MySQL 索引
Posted
技术标签:
【中文标题】ORDER BY A*B 的 MySQL 索引【英文标题】:MySQL index for ORDER BY A*B 【发布时间】:2014-08-10 09:09:45 【问题描述】:我有一个 mysql InnoDB 表,其中包含两个 INT
列,例如 col1
和 col2
。我想添加一个索引,让我能够:
SELECT * from myTable WHERE col0=5 ORDER BY col1*col2 DESC
是否有可能有一个支持这种排序的索引,或者我需要添加一个保留该值的列(col1*col2
)?
【问题讨论】:
我不这么认为。索引只是列,不用于存储表达式。 你为什么需要一个索引? 如果col0
上有索引,则可能会使用 WHERE 子句中的索引。如果查询没有返回太多匹配项,a*b
排序不会受到影响。
@Strawberry @Jonny 你说得对,如果WHERE
没有返回太多匹配项,排序不会受到影响,但它确实(在 C*100k 范围内)跨度>
诺姆,见ORDER BY Optimization。如果有使用key1
的WHERE 子句,key2
可能不能用于排序。只有key1
或最终key1
的一部分。也许可行,将col1*col2
放在另一列中,但将一个索引放在col0
和order_col
上。检查 EXPLAIN SELECT...
【参考方案1】:
诺姆,见ORDER BY Optimization。如果要使用索引进行排序,它应该与索引相同,即在 WHERE 子句中使用,当然排序值需要存储在它自己的列中。 Here I generated a test table with 100k rows,应该符合你的情况。
1.) 在两列上添加 ONE INDEX(这适用于使用索引进行选择和排序):
ALTER TABLE `test_data` ADD INDEX super_sort (`col0`,`sort_col`);
EXPLAIN SELECT * FROM `test_data` WHERE col0 = 50 ORDER BY sort_col;
key -> super_sort;额外 -> 使用 where (索引用于 WHERE 和 SORT)
2.) 添加两个索引,一个用于 WHERE,一个用于 SORT(不起作用)
ALTER TABLE `test_data` DROP INDEX `super_sort`;
ALTER TABLE `test_data` ADD INDEX (`col0`);
ALTER TABLE `test_data` ADD INDEX (`sort_col`);
EXPLAIN SELECT * FROM `test_data` WHERE col0 = 50 ORDER BY sort_col;
键-> col0;额外 -> 使用 where;使用文件排序 (索引用于 WHERE,但不用于排序)
所以答案是:是的,您需要一列来保持该值 (col1*col2)
并且您需要在两列上都有一个索引:col0
(用于 WHERE 子句)+ sort_col
(用于排序)就像第一个例子一样。只要您ORDER BY
进行任何计算(例如col1*col2
),就没有索引可用于排序。
【讨论】:
【参考方案2】:您可以添加包含col1*col2
值的新列并将其用于排序。否则你可以使用SELECT * from myTable WHERE col0=5 ORDER BY col1*col2 DESC
。
【讨论】:
那一栏的原因是什么? 我的意思是两种方法都可以,但是在从数千行读取数据时保留新列会使其更快,并且在使用新列存储数据时会出现存储问题。 你仍然没有解释为什么你的答案是正确的;问题本身表明这是可能的,但问题是询问是否需要这样做,或者是否可以使用某种索引。 不过,你可以介绍一些其他的方法,如果你知道的话,那会更快。 如果可能,请使用正确的代码块和语法。以上是关于ORDER BY A*B 的 MySQL 索引的主要内容,如果未能解决你的问题,请参考以下文章
MySQL 原理分析之 Trace 分析 order by 的索引原理