GROUP BY与ORDER BY数据库速度极慢(似乎创建临时表)

Joe*_*oey -1 mysql sql database-performance

我正在构建一个Twitter应用程序,在twitter上显示已发布的链接,但我在按时间排序表时遇到问题.

tweet
+----------------------------------------+
| tweet_id | [...] | created_at          |
+----------------------------------------+  
| 123456   | [...] | 2012-06-11 11:31:28 |
| 234567   | [...] | 2012-06-11 11:32:55 |
| 345678   | [...] | 2012-06-11 11:33:22 |
+----------------------------------------+

tweets_url
+---------------------+
| tweet_id | url      |
+---------------------+
| 123456   | cnn.com  |
| 123456   | fox.com  |
| 234567   | abc.com  |
| 345678   | abc.com  |
+---------------------+
Run Code Online (Sandbox Code Playgroud)

继承我的SQL(我使用GROUP by只返回唯一的URL):

SELECT tweet_urls.url,
    FROM  `tweets` 
    LEFT JOIN tweet_urls ON tweet_urls.tweet_id = tweets.tweet_id 
    WHERE tweet_urls.url LIKE '%cnn.com%'
    GROUP BY tweet_urls.url 
    ORDER BY tweets.created_at DESC LIMIT 0 , 20
Run Code Online (Sandbox Code Playgroud)

我尝试使用不同的连接和内部SELECTS 从此处使用外部选择运行此查询的不同变体.

编辑:我做了一些进一步的测试.似乎Mysql基于GROUP BY tweet_urls.url创建了一个临时表,然后使用指定的索引对结果进行排序,因为它在临时表上运行.

这是EXPLAIN输出:

+----+-------------+------------+--------+---------------+---------+---------+-----+----------------------+----------------------------------------------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref |                rows  | Extra                                        |
+---------------------------------------------------------------------------------------------------------+----------------------------------------------+
| 1  | SIMPLE      | tweet_urls | index  | tweet_id      | url     | 422     | NULL                 86783 | Using where; Using temporary; Using filesort 
| 1  | SIMPLE      | tweets     | eq_ref | PRIMARY       | PRIMARY | 8       | tweet_urls.tweet_id        |
+----+-------------+------------+--------+---------------+---------+---------+-----+----------------------+----------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 7

我认为真正的问题在于:

WHERE tweet_urls.url LIKE '%cnn.com%'
Run Code Online (Sandbox Code Playgroud)

这种类型的查询(LIKE没有常量前缀)无法有效地使用索引.

您可以通过向表中添加一个额外的列来解决此问题,domain并对其进行索引和索引.然后,您可以将查询更改为:

WHERE tweet_urls.domain = 'cnn.com'
Run Code Online (Sandbox Code Playgroud)