MySQL索引列排序缓慢问题

3

我有一个表(book_list)约有400万条记录。它有一个主键(book_list_id),当我运行像下面这样的查询时,我可以在0.060秒内得到结果。

 select * from book_list bl ORDER BY bl.book_list_id LIMIT 25

现在,当我运行几乎相同的查询,但按照书名排序(它是varchar(1200)类型并且已经建立索引),需要34.7秒。

 select * from book_list bl ORDER BY bl.book_title LIMIT 25

有没有什么方法可以让第二个语句更快?

顺便提一下,我还尝试了按其他数字索引字段排序,它们也非常慢。只有主键排序似乎产生了快速的结果。

这是创建表的代码:

CREATE TABLE `book_list` (

`book_list_id` int(11) NOT NULL AUTO_INCREMENT,

`book_title` varchar(1200) CHARACTER SET utf8 DEFAULT NULL
 PRIMARY KEY (`book_list_id`),

 KEY `indx_book_title` (`book_title`(255))

 ) 
 ENGINE=InnoDB AUTO_INCREMENT=4733798 DEFAULT CHARSET=latin1

3
运行“explain…”会显示什么? - Dmitry B.
书名是varchar 1200而不是varchar 200。允许为空,你有很多空值吗? - dani herrera
2
也许原因就在于整数列的单个索引条目为4字节,而varchar列为766字节。这是要比较的更大数据量。 - Hammerite
1
Hammerite是正确的。如果标题长度为1200,索引长度为255,则RDBMS应重新排列剩余的1200-255个字符的行,也许是这样?34.7秒是很长的时间,在这段中间时间中瓶颈在哪里?磁盘?CPU?这能帮助解决这个问题吗?如果您通过标题获取前25行的pk,并查询请求这些硬编码的pks,速度会快吗? - dani herrera
2
你还可以使用'order by left(book_title, 255)',这样就不会有任何问题使用索引了。虽然,仍然可能会出现超过255个字符的标题无法按顺序排列的情况。但至少你可以在不对数据库进行任何更改的情况下测试这个理论。 - Dmitry B.
显示剩余9条评论
2个回答

2

性能不佳是因为并非所有字段都被索引,只有前255个字符。关系型数据库系统必须比较1200-255个字符才能进行最终排序。

增加被索引的字段部分或者按照@Dmitry Beransky所说只通过前255个字符进行排序: 'order by left(book_title, 255)'


-2

请尝试一下:

select * from book_list where book_list_id in
(select book_list_id from book_list order by book_title limit 25);

这会导致以下错误:[Err] 1235 - 这个版本的MySQL还不支持'LIMIT & IN/ALL/ANY/SOME子查询'。 - chrisg229

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接