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行。
我仍在等待查询完成。 有谁知道在更短的时间内工作的方法?
答案 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
,后跟表名。