MySQL“SELECT DISTINCT”非常大的表的效率

时间:2012-05-29 13:44:53

标签: mysql performance

我有一个非常大的表(数百万条记录),包含大约8个字段作为主键。为了简单起见,我们可以说表格如下:

    key_1 | key_2 | key_3 | ... | key_8 | value

给出key_1的值,我需要获取key_2,key_3,...,key_8的所有可能值 以下内容:

    SELECT DISTINCT key_2 FROM table1 WHERE key_1 = 123;
    SELECT DISTINCT key_3 FROM table1 WHERE key_1 = 123;
    ...
    SELECT DISTINCT key_8 FROM table1 WHERE key_1 = 123;

我的问题是这个查询明显慢于我的性能需求,并且此表中的数据相当稳定且很少更新(每隔几天一次)。 table_1也可能是一个缓慢的子查询。如果没有在数据库中创建额外的表并在每次更新数据库时手动更新它,是否有另一种解决方案可以为我提供快速结果。我需要它来处理多个MySQL会话。

2 个答案:

答案 0 :(得分:15)

无法用我们掌握的信息给出明确的答案,但让我们从这些开始:

你有关于key_1的索引吗?

没有它,每个查询本身就会很慢,只需要查找123。

你有(key_1,key_2)的索引吗?

因为select distinct key_2 where key_1 = 123非常快,只要它能从索引中获取所有必要的数据。无需访问该表。

行/索引是固定大小的吗?

遍历固定大小的表/行可以更快,因为通过计算偏移总是知道第x个记录的位置。变量行大小的表格较慢。

您是否尝试添加自动增量代理主键?

当所有必须存储的索引是列和小主键时,索引的工作方式会更好。复合主键较慢。

您是否考虑过只读表?

您可以打包myisam表以便快速访问,但它们变为只读。这是一个有其用途的黑客。

更进一步,你考虑过一个数据仓库吗?

如果表格不经常更改,最好复制信息以便快速访问。

您可以发布show create table声明吗?查看列和索引会有所帮助。 你能发表一个explain select声明吗?查看使用哪些索引会有所帮助。

答案 1 :(得分:2)

SELECT DISTINCT key_2 FROM table1 WHERE key_1 = 123;

这可以使用您的主键索引(key_1,key_2等)它将执行索引扫描,这比表扫描或临时表快。

SELECT DISTINCT key_3 FROM table1 WHERE key_1 = 123;

无法使用主键,因为key_1和key_3的组合不会形成主键的前缀。您需要按顺序在key_1和key_3上创建复合索引。然后,它也可以使用该索引来执行索引扫描。

SELECT DISTINCT key_8 FROM table1 WHERE key_1 = 123;

按顺序需要key_1和key_8的索引。与上述相同。