我有一张有450000行新闻的桌子。表模式如下所示:
CREATE TABLE IF NOT EXISTS `news` (
`id` int(11) NOT NULL auto_increment,
`cat_id` int(11) NOT NULL,
`title` tinytext NOT NULL,
`content` text NOT NULL,
`date` int(11) NOT NULL,
`readcount` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `cat_id` (`cat_id`),
KEY `cat_id_2` (`cat_id`,`id`),
KEY `cat_id_date` (`cat_id`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=latin5 AUTO_INCREMENT=462679 ;当我运行下面这样的sql命令来获取分类页面的页面"x“的一些新闻时,如果x超过100,则需要15秒以上的时间:
select * news where cat_id='4' order by id desc limit 150000,10;explain显示它使用"where“和索引"cat_id_2”
在写这个问题的时候,我还检查了一个更简单的sql查询,也花了将近一分钟的时间:
select * from haberler order by id desc limit 40000,10;如果sql类似于下面的sql,那么只需要几毫秒:
select * from haberler order by id desc limit 20,10;我的my.cnf配置如下:
skip-locking
skip-innodb
query_cache_limit=1M
query_cache_size=256M
query_cache_type=1
max_connections=30
interactive_timeout=600000
#wait_timeout=5
#connect_timeout=5
thread_cache_size=384
key_buffer=256M
join_buffer=4M
max_allowed_packet=16M
table_cache=1024
record_buffer=1M
sort_buffer_size=64M
read_buffer_size=16M
max_connect_errors=10
# Try number of CPU's*2 for thread_concurrency
thread_concurrency=2
myisam_sort_buffer_size=128M
long_query_time = 1
log_slow_queries = /var/log/mysql/mysql-slow.log
max_heap_table_size=512M该网站运行在内存为2 2GB的core2duo上。我认为这个问题可能是由sort_buffer_size引起的,但我不确定。提前谢谢。
发布于 2009-10-23 20:07:51
更新:
有关这个问题的更详细分析,请参阅我的博客中的这篇文章:
当您发出像LIMIT 150000, 10这样的命令时,这意味着MySQL应该遍历这些150,000记录并找到下一个10。
在MySQL中,遍历索引的速度很慢。
此外,MySQL不能执行后期行查找。
从理论上讲,如果使用ORDER BY id LIMIT 100000, 10,使用索引查找从100000到100010的值就足够了,然后只查找满足该索引的10行并返回它们。
除了MySQL之外的所有主要系统都知道这一点,并且只有在真正返回值的情况下才会查找行。
然而,MySQL会查找每一行。
尝试将您的查询重写为:
SELECT news.*
FROM (
SELECT id
FROM news
WHERE cat_id='4'
ORDER BY
id DESC
LIMIT 150000, 10
) o
JOIN news
ON news.id = o.idhttps://stackoverflow.com/questions/1612957
复制相似问题