3

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

现在有什么问题?

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

我正在考虑的解决方案是什么?

为需要排序的表的每一列添加索引!就我而言,我将在 8 列上有索引!!!!

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

在列上有大量索引可能会降低 INSERT/UPDATE 查询的速度!就我而言,表格经常更新(每秒!!!!!!)

您对这种情况有什么解决方案?!

4

2 回答 2

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 BorORDER 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 决定将其传递下去。

于 2012-10-02T07:44:21.867 回答
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,因为我使用了一段时间后非常满意,但我也听说过弹性搜索。

于 2012-10-02T10:38:04.350 回答