MySQL - 按列排序,在大表中有许多不同的值

时间:2017-03-18 18:56:40

标签: mysql sql database optimization

可能通过糟糕的数据库设计,以下非常简单的查询需要大约1.5分钟才能运行。

SELECT  s.title, t.name AS team_name
    FROM  stories AS s
    JOIN  teams AS t  ON s.team_id = t.id
    WHERE  s.pubdate >= "1970-01-01 00:00"
    ORDER BY  s.hits /* <-- here's the problem */
    LIMIT  3 OFFSET 0 

问题是stories表格相当大,行数约为1.5米,hits有很多唯一值(此列记录每个故事的点击数。)

取出订单条款,它几乎立即解决。

问题:如何优化此类查询?据推测,我不应该将索引应用于hits,因为该列上不会直接查找索引。

[UPDATE]

所有相关表格的

SHOW CREATE TABLE

CREATE TABLE stories (
 `id` varchar(11) NOT NULL,
 `link` text NOT NULL,
 `title` varchar(255) CHARACTER SET utf8 NOT NULL,
 `description` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
 `pubdate` datetime NOT NULL,
 `source_id` varchar(11) NOT NULL,
 `team_id` varchar(11) NOT NULL,
 `hits` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `Unique combo (title + date)` (`title`,`pubdate`),
 KEY `team (FK)` (`team_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

CREATE TABLE teams (
 `id` varchar(11) NOT NULL,
 `is_live` enum('y') DEFAULT NULL,
 `name` varchar(50) NOT NULL,
 `short_name` varchar(12) DEFAULT NULL,
 `server` varchar(11) DEFAULT NULL,
 `url_token` varchar(255) NOT NULL,
 `league` varchar(11) NOT NULL,
 `away_game_id` varchar(255) DEFAULT NULL,
 `digest_list_id` varchar(25) DEFAULT NULL,
 `twitter_handle` varchar(255) DEFAULT NULL,
 `no_official_news` enum('y') DEFAULT NULL,
 `alt_names` varchar(255) DEFAULT NULL,
 `no_use_nickname` enum('y') DEFAULT NULL,
 `official_hashtag` varchar(30) DEFAULT NULL,
 `merge_news_and_fans` enum('y') DEFAULT NULL,
 `colour_1` varchar(6) NOT NULL,
 `colour_2` varchar(6) DEFAULT NULL,
 `colour_3` varchar(6) DEFAULT NULL,
 `link_colour_modifier` float DEFAULT NULL,
 `alt_link_colour_modifier` float DEFAULT NULL,
 `title_shade` enum('dark','light') NOT NULL,
 `shirt_style` enum('vert_stripes','horiz_stripes','vert_stripes_thin','horiz_stripes_thin','vert_split','horiz_split') DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `URL token` (`url_token`),
 KEY `league (FK)` (`league`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

1 个答案:

答案 0 :(得分:1)

如果用户不需要,请考虑删除pubdate上的过滤器。它让优化器感到困惑。

INDEX(hits, pubdate, title)

可能最有助于查询。它是“覆盖”。

删除ORDER BY快速运行的原因:没有它,它会为您提供任何 3行。有了它,没有有用的索引,它需要对1.5M行进行排序以发现具有最少命中数的3。

也许你想要ORDER BY s.hits DESC? - 获得那些大多数点击的人。