Mysql索引配置

int*_*cto 7 mysql sql performance

我有一张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 ;
Run Code Online (Sandbox Code Playgroud)

当我运行如下的sql命令为类别页面的页面"x"获取一些新闻时,如果x超过100则需要超过15秒:

select * news where cat_id='4' order by id desc limit 150000,10;
Run Code Online (Sandbox Code Playgroud)

解释说明它使用"where"和索引"cat_id_2"

在写这个问题时,我还检查了一个更简单的SQL查询,这也花了近一分钟:

select * from haberler order by id desc limit 40000,10;
Run Code Online (Sandbox Code Playgroud)

如果sql如下所示,只需几毫秒:

select * from haberler order by id desc limit 20,10;
Run Code Online (Sandbox Code Playgroud)

我的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
Run Code Online (Sandbox Code Playgroud)

该网站运行在core2duo上,内存为2GB.我认为问题可能是由sort_buffer_size引起的,但我不确定.提前致谢.

Qua*_*noi 19

更新:

有关问题的详细分析,请参阅我的博客中的这篇文章:


当你发出类似的东西时LIMIT 150000, 10,它意味着MySQL应该遍历这些150,000记录并找到下一个记录10.

遍历索引很慢MySQL.

此外,MySQL无法进行后期行查找.

从理论上讲,如果你这样做ORDER BY id LIMIT 100000, 10,这是足够使用索引找到从价值观100000100010,再看看只有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.id
Run Code Online (Sandbox Code Playgroud)