我有一个包含 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;
解释表明它使用“where”和索引“cat_id_2”
在写这个问题时,我还检查了一个更简单的 sql 查询,这样也花了将近一分钟的时间:
select * from haberler order by id desc limit 40000,10;
如果 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
该网站在具有 2GB 内存的 core2duo 上运行。 我认为问题可能是由 sort_buffer_size 引起的,但我不确定。 提前致谢。
最佳答案
更新:
更详细的问题分析见我博客中的这篇文章:
当您发出类似 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.id
关于sql - mysql索引配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1612957/