|
我上有4500万行新闻。表架构如下:6 K& X9 |* I+ [# c% e6 C e4 m; q
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秒以上:; V' R5 }6 K' r- u M2 F
select * news where cat_id='4' order by id desc limit 150000,10;说明显示其使用 where和索引 cat_id_2”% F1 A- M. m/ w& i, ]& I
在写这个问题的时候,我也检查了一个更简单的问题sql查询也花了将近一分钟:; V1 E$ R8 d; k* l
select * from haberler order by id desc limit 40000,10;如果sql类似于以下内容,只需几毫秒:9 h4 x8 K" ?) S7 _# g3 @
select * from haberler order by id desc limit 20,10;我的my.cnf配置如下:
! \" j; z6 g. ?. P3 gskip-lockingskip-innodbquery_cache_limit=1Mquery_cache_size=256Mquery_cache_type=1max_connections=30interactive_timeout=600000#wait_timeout=5#connect_timeout=5thread_cache_size=384key_buffer=256Mjoin_buffer=4Mmax_allowed_packet=16Mtable_cache=1024record_buffer=1Msort_buffer_size=64Mread_buffer_size=16Mmax_connect_errors=10# Try number of CPU's*2 for thread_concurrencythread_concurrency=2myisam_sort_buffer_size=128Mlong_query_time = 1log_slow_queries = /var/log/mysql/mysql-slow.logmax_heap_table_size=512M该网站运行在2GB RAM的core2duo上去。我认为问题可能是由于sort_buffer_size但我不确定。提前感谢。
C1 n" j/ ~9 o) J1 C
/ N* x7 _% ^8 E) H7 |; R! v* k0 j/ S 解决方案: , R' q2 Q4 c: b; g
更新:+ R; {; ^. ]$ |/ T7 I! U3 q0 O
请参阅我的博客中的这篇文章,以便更详细地分析问题:
+ B, t' D( U; s: `. \MySQL ORDER BY / LIMIT性能:晚行搜索当您发送类似内容时LIMIT 1.5万,10意味着MySQL记录这些150000,并查找下一个10。7 X Y) o: p7 e* I$ Q
中遍历索引非常慢MySQL。* Q- J( k. ]# q6 m/ x1 B, ]
同样,MySQL以后不能搜索。
! r) S/ g, T5 i3 G理论上,如果你这样做的话ORDER BY id LIMIT 1万,10,足以用索引找到1万到1万的价值观,然后看到只有10满足该指数并返回它们。$ K, P, h* {; h& v3 n* [
除主要值外MySQL,所有主要系统都会意识到这一点,只有在确实需要返回值时才能向上搜索。
. J& m9 }6 e! r8 A/ @+ BMySQL,但是,每行都要找一次。
7 m0 Y. [* ~; ~7 k7 b' D$ @试着这样重写查询:% U3 c$ D- P' Q- i
SELECT news.*FROM ( SELECT id FROM news WHERE cat_id= ORDER BY id DESC LIMIT oJOIN newsON news.id = o.id |
|