mysql从百万条记录中获取列连接的平均值

时间:2018-10-21 20:13:04

标签: mysql query-performance

SELECT AVG(table1.column1) as a,
       table2.column2
FROM table1
    LEFT OUTER JOIN table2
        ON table2.column2 = table1.column2
GROUP BY table2.column2 ORDER BY a DESC LIMIT 10

这是MySQL代码。我在表1中有150万行,在表2中有200.000行。

我仍在等待查询完成。 有谁知道在更短的时间内工作的方法?

1 个答案:

答案 0 :(得分:0)

很多评论都以同样的方式出现,但我想我会给出一个彻底的答案。我将在这里使用我自己的表/数据库之一进行解释。我们来看一下这个查询:

SELECT A.id, B.asin FROM AmazonWishlistItems A LEFT JOIN AmazonWishlistItemPrices B ON (B.asin = A.asin) WHERE A.asin LIKE "%C%"

此查询返回大约851,耗时0.5秒。如果我们在查询中添加单词EXPLAIN,MySQL会告诉我们该查询在做什么。

mysql> EXPLAIN SELECT A.id, B.asin FROM AmazonWishlistItems A LEFT JOIN AmazonWishlistItemPrices B ON (B.asin = A.asin) WHERE A.asin LIKE "%C%";
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | A     | ALL  | NULL          | NULL | NULL    | NULL | 1183 | Using where |
|  1 | SIMPLE      | B     | ALL  | NULL          | NULL | NULL    | NULL | 6594 |             |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
2 rows in set (0.00 sec)

这里要查看的重要列是rows,因为这是MySQL必须查看的记录数,在这种情况下,对于表A和B,它必须查找所有行,即使有仅851个符合条件。这是表格可以快速失控的方式,该表格只能搜索6594条记录,但仅此一项就可以轻松达到150万行。

因此,我们可以通过在表中添加索引来减少这种情况,允许MySQL为每个记录存储一个引用。

ALTER TABLE AmazonWishlistItemPrices ADD INDEX idx_asin (asin)

这只是说创建一个名为idx_asin的索引,并使用列asin进行索引。如果我们重新运行EXPLAIN ...

mysql> EXPLAIN SELECT A.id, B.asin FROM AmazonWishlistItems A LEFT JOIN AmazonWishlistItemPrices B ON (B.asin = A.asin) WHERE A.asin LIKE "%C%";
+----+-------------+-------+------+---------------+----------+---------+---------------------+------+-------------+
| id | select_type | table | type | possible_keys | key      | key_len | ref                 | rows | Extra       |
+----+-------------+-------+------+---------------+----------+---------+---------------------+------+-------------+
|  1 | SIMPLE      | A     | ALL  | NULL          | NULL     | NULL    | NULL                | 1183 | Using where |
|  1 | SIMPLE      | B     | ref  | idx_asin      | idx_asin | 12      | mah_database.A.asin |    6 | Using index |
+----+-------------+-------+------+---------------+----------+---------+---------------------+------+-------------+
2 rows in set (0.00 sec)

我们只有6行,您可以在possible_keys中看到我们的索引。您可能会发现,由于您在WHERE条件中提供的条件,对于某些联接和where子句,您的索引将被忽略,这只是MySQL所说的“无论如何我都必须获取所有数据”。

最好使用数字键进行索引,您可以使用一些varchar,但是它们确实占用了磁盘空间。尽可能在每个表上都有一个PRIMARY KEY。因此,请查看您的数据库结构并考虑添加一些索引。

检查表是否具有索引的最后一件事,可以使用SHOW CREATE TABLE,后跟表名。