在mysql中按列排序并使用索引的最佳方法是什么?

时间:2012-10-02 07:34:33

标签: mysql optimization indexing

我有一个包含10列的表,现在我想让用户可以选择使用他们想要的任何列对数据进行排序。例如,假设一个包含7个项目的组合框,每个项目都是表格的一列,现在用户选择一个项目并获取按所选列排序的数据。

现在有什么问题?

我的表有3M记录,如果我用索引列对数据进行排序我没有问题但是使用非索引列需要3.5分钟来排序!!!

我在想什么解决方案?

将索引添加到需要排序的表的每一列!在我的情况下,我将有8列索引!!!!

我的解决方案有什么问题?

列上有很多索引可能会降低INSERT / UPDATE查询的速度!在我的情况下,表经常更新(每秒!!!!!)

这个案例的解决方案是什么?!

2 个答案:

答案 0 :(得分:0)

阅读本文以获取有关优化的更多详细信息:http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

在某些情况下,MySQL无法使用索引来解析ORDER BY,尽管它仍然使用索引来查找与WHERE子句匹配的行。使用索引进行排序通常与使用索引一起查找行,但是它也可以仅用于排序,例如,如果您只是在表上使用ORDER BY without和where子句。在这种情况下,您会在EXPLAIN中看到“索引”类型,它对应于索引顺序中的扫描(可能)完整表。了解在哪些条件下可以使用索引对数据进行排序以及限制行数非常重要。

查看相同的索引(A,B)ORDER BY A ; ORDER BY A,B ; ORDER BY A DESC, B DESC之类的东西将能够使用完整索引进行排序(注意如果排序,MySQL可能不会选择使用索引进行排序没有限制的全桌)。但是ORDER BY BORDER BY A, B DESC将无法使用索引,因为请求的订单不符合BTREE中的数据顺序。如果你有限制和排序这样的事情可以工作A=5 ORDER BY B ; A=5 ORDER BY B DESC; A>5 ORDER BY A ; A>5 ORDER BY A,B ; A>5 ORDER BY A DESC,这可以很容易地被视为扫描BTREE中的范围。然而,这样的事情不起作用A>5 ORDER BY B , A>5 ORDER BY A,B DESC or A IN (3,4) ORDER BY B - 在这些情况下,以排序形式获取数据需要的不仅仅是BTREE中的简单范围扫描,MySQL决定将其传递。

答案 1 :(得分:0)

选项#1 :如果您仅限于MySQL,则没有更好的选择,但为可能的订单列创建8个索引。您的插入/更新肯定会受到影响,但没有真正的访问者会等待3.5分钟才能对列表进行排序。

调整#1:为了使它快一点,您可以创建部分索引而不是标准索引,这将使用更少的空间(我假设其中一些列是varchar),这意味着更少的写入,更小的内存占用。您只需要使用子字符串检查每列的熵,并确保您仍然有超过90%的区别。

例如,使用如下查询:

> select count(distinct(substring(COLUMN, 1, 5))) as part_5, count(distinct(substring(COLUMN, 1, 10))) as part_10, count(distinct(substring(COLUMN, 1, 20))) as part_20, count(distinct(COLUMN)) as sum from TABLE;
+--------+---------+---------+---------+
| part_5 | part_10 | part_20 | sum     |
+--------+---------+---------+---------+
| 892183 | 1996053 | 1996058 | 1996058 |
+--------+---------+---------+---------+

调整#2:您可以插入/更新语句以在后台执行。应用程序不会更快,但用户体验会更好。

调整#3:如果可以进行插入/更新,请使用更大的事务。

选项#2 :您可以尝试使用为此使用模式构建的搜索引擎之一(也是)。我会推荐Solr因为我已经使用了一段时间而且非常满意但我也听说过弹性搜索。