2009-10-23 69 views
7

我有一個450000行充滿新聞的表。 表架構是這樣的:Mysql索引配置

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」分類頁面的花費超過15秒,如果x超過100:

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 

該網站上的Core 2 Duo運行與2GB的RAM。 我認爲這個問題可能是由sort_buffer_size引起的,但我不確定。 在此先感謝。

+0

也可能是您的索引,你有沒有考慮這方面? – 2009-10-23 11:58:00

+0

您的問題存在一些不一致之處,請您將其編輯以使其更清楚? – 2009-10-23 12:03:01

+0

它現在必須修好,表中使用的名字本來就是土耳其語,似乎我忘了將它們中的一些翻譯成英文。 對不起我的壞英語的方式。 – intacto 2009-10-23 12:45:57

回答

17

更新:

看到這篇文章在我的博客對這個問題的更詳細的分析:


當你發出類似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 
+0

您的查詢似乎工作得更快,但我無法理解原因。 你能說出原因嗎? – intacto 2009-10-23 12:25:12

+1

後期查詢,我在我的文章中描述過。我的查詢只從表中選擇'10'記錄,你的原始查詢選擇所有'150,000'記錄並丟棄它們。我將在今天晚上發表一篇關於此的博客文章,我將在其中詳細介紹。 – Quassnoi 2009-10-23 12:32:55

+0

所以採取只是身份證使得它更快,得到它,謝謝.. – intacto 2009-10-23 12:35:57